<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>antek&#x27;s tech blog - linux</title>
    <link rel="self" type="application/atom+xml" href="https://anadoxin.org/blog/tags/linux/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://anadoxin.org/blog"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-03-31T00:00:00+00:00</updated>
    <id>https://anadoxin.org/blog/tags/linux/atom.xml</id>
    <entry xml:lang="en">
        <title>Intercepting HTTPS traffic from a VM for debugging</title>
        <published>2026-03-31T00:00:00+00:00</published>
        <updated>2026-03-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/intercepting-ssl-traffic/"/>
        <id>https://anadoxin.org/blog/intercepting-ssl-traffic/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/intercepting-ssl-traffic/">&lt;p&gt;Hi,&lt;&#x2F;p&gt;
&lt;p&gt;In the good old days, when the Earth was young and the Internet was a
wild west of plain, non-commercial unencrypted text, intercepting
traffic during development was trivially easy. You&#x27;d fire up Ethereal
(now Wireshark), pick the right interface, and watch every byte of
every HTTP request fly by. Life was simple.&lt;&#x2F;p&gt;
&lt;p&gt;Then Let&#x27;s Encrypt happened, HTTPS became mandatory, and now
everything you want to inspect is wrapped in TLS. Not a bad thing for
production, but not very convenient when you&#x27;re trying to figure out
why your HTTP client is sending malformed headers or why a third-party
API is returning a 400 with no explanation. Especially in current
times where application errors are signalled only by &quot;please contact
your administrator&quot;, or &quot;something went wrong, please try again later&quot;
messages.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, there are a few ways to solve this inspection
problem. &lt;code&gt;SSLKEYLOGFILE&lt;&#x2F;code&gt; works if the library you&#x27;re using supports it
(&lt;code&gt;libcurl&lt;&#x2F;code&gt; does, most things don&#x27;t). Burp Suite is popular in the
security world. Http Toolkit sometimes works. But the cleanest
approach I&#x27;ve found for inspecting traffic from a VM is to run a
transparent proxy on the host using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mitmproxy.org&quot;&gt;mitmproxy&lt;&#x2F;a&gt;, and
silently redirect all the VM&#x27;s traffic through it with &lt;code&gt;iptables&lt;&#x2F;code&gt;. No
changes required inside the VM -- other than trusting the proxy&#x27;s CA
certificate.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s the full setup.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-environment&quot;&gt;The environment&lt;&#x2F;h2&gt;
&lt;p&gt;The VM is a Windows 10 guest running under &lt;code&gt;libvirt&lt;&#x2F;code&gt;&#x2F;QEMU on a Linux host.
The guest is connected to the default libvirt bridge &lt;code&gt;virbr0&lt;&#x2F;code&gt;, which is a NAT
network -- meaning all traffic from the VM goes through the host. It&#x27;s the
default and easiest setup possible, and that&#x27;s the part we&#x27;ll exploit.&lt;&#x2F;p&gt;
&lt;p&gt;The host needs a few things to be in order. First, IP forwarding must be
enabled, because the host acts as a router for the VM:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; sysctl net.ipv4.ip_forward&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;net.ipv4.ip_forward&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;       # Must be 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Good. Second, we need &lt;code&gt;iptables&lt;&#x2F;code&gt; to be able to see traffic that flows through
the bridge. By default, bridged packets bypass the netfilter rules entirely.
The &lt;code&gt;br_netfilter&lt;&#x2F;code&gt; kernel module fixes this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# modprobe br_netfilter&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# cat &#x2F;proc&#x2F;sys&#x2F;net&#x2F;bridge&#x2F;bridge-nf-call-iptables&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;                             # Must be 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With that in place, &lt;code&gt;iptables&lt;&#x2F;code&gt; rules will actually fire on packets arriving on
&lt;code&gt;virbr0&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;redirecting-traffic-with-iptables&quot;&gt;Redirecting traffic with iptables&lt;&#x2F;h2&gt;
&lt;p&gt;Now we tell the kernel to redirect all TCP traffic from the VM on ports 80 and
443 to port 8000 on the host, where mitmproxy will be listening:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# iptables -t nat -A PREROUTING -i virbr0 -p tcp --dport 443 -j REDIRECT --to-port 8000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# iptables -t nat -A PREROUTING -i virbr0 -p tcp --dport 80  -j REDIRECT --to-port 8000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Verify with:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# iptables -t nat -L -v -n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Chain&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; PREROUTING&lt;&#x2F;span&gt;&lt;span&gt; (policy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; ACCEPT ...&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; pkts&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; bytes target     prot opt in     out     source               destination&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;     0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; REDIRECT   tcp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;  --&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;  virbr0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;       0.0.0.0&#x2F;0            0.0.0.0&#x2F;0    tcp dpt:443 redir ports&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 8000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;     0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; REDIRECT   tcp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;  --&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;  virbr0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;       0.0.0.0&#x2F;0            0.0.0.0&#x2F;0    tcp dpt:80  redir ports&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 8000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;PREROUTING&lt;&#x2F;code&gt; chain intercepts packets as they arrive -- before any routing
decision is made -- which is exactly what we want. The &lt;code&gt;REDIRECT&lt;&#x2F;code&gt; target
rewrites the destination to &lt;code&gt;127.0.0.1:8000&lt;&#x2F;code&gt; on the host.&lt;&#x2F;p&gt;
&lt;p&gt;Note that these rules are &lt;strong&gt;not persistent&lt;&#x2F;strong&gt; across reboots. If you want them
to survive, use whatever mechanism your distro provides (&lt;code&gt;iptables-save&lt;&#x2F;code&gt; &#x2F;
&lt;code&gt;iptables-restore&lt;&#x2F;code&gt;, or a service that loads the rules on startup). For
debugging sessions, I find temporary rules are actually more convenient -- they
disappear cleanly when you&#x27;re done. You can always write yourself a script
to bring them up with just a simple script call.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;a-note-on-nftables&quot;&gt;A note on nftables&lt;&#x2F;h3&gt;
&lt;p&gt;On newer distributions, &lt;code&gt;iptables&lt;&#x2F;code&gt; is often just a compatibility shim
over &lt;code&gt;nftables&lt;&#x2F;code&gt;, the modern successor to the old
&lt;code&gt;{ip,ip6,arp,eb}tables&lt;&#x2F;code&gt; family. If your distro has migrated fully, the
&lt;code&gt;iptables&lt;&#x2F;code&gt; command might not even be available. If &lt;code&gt;iptables&lt;&#x2F;code&gt; is missing
on your distro, verify that maybe you have the &lt;code&gt;nft&lt;&#x2F;code&gt; command instead.&lt;&#x2F;p&gt;
&lt;p&gt;If it&#x27;s present, the equivalent ruleset in &lt;code&gt;nft&lt;&#x2F;code&gt; syntax would look
like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# nft add table ip nat&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# nft add chain ip nat PREROUTING &amp;#39;{ type nat hook prerouting priority -100; }&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# nft add rule ip nat PREROUTING iifname &amp;quot;virbr0&amp;quot; tcp dport 443 redirect to :8000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# nft add rule ip nat PREROUTING iifname &amp;quot;virbr0&amp;quot; tcp dport 80  redirect to :8000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In my case &lt;code&gt;iptables&lt;&#x2F;code&gt; was still available and worked fine, so I stuck with it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;http-3-and-the-quic-problem&quot;&gt;HTTP&#x2F;3 and the QUIC problem&lt;&#x2F;h2&gt;
&lt;p&gt;There is a catch that&#x27;s really easy to overlook. The rules above only
handle TCP traffic. The &quot;good old&quot; HTTP&#x2F;1.1 and HTTP&#x2F;2 run over TCP,
so they&#x27;re covered. But HTTP&#x2F;3 is a different story.&lt;&#x2F;p&gt;
&lt;p&gt;HTTP&#x2F;3 is built on top of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;datatracker.ietf.org&#x2F;doc&#x2F;html&#x2F;rfc9000&quot;&gt;QUIC&lt;&#x2F;a&gt; -- a transport protocol
standardized by the IETF (RFC 9000). Unlike its predecessors, QUIC
runs over &lt;strong&gt;UDP&lt;&#x2F;strong&gt;, not TCP. It was designed to solve some fundamental
Google problems, and since Google has tons of money to burn, they&#x27;ve
decided to burn it on QUIC adoption. So, we&#x27;re stuck with it now. It
may address some of the HTTP&#x2F;1.1 and HTTP&#x2F;2 problems, but to be honest,
I don&#x27;t really know.&lt;&#x2F;p&gt;
&lt;p&gt;The practical implication for our setup is that if the client is a modern
browser, it will likely attempt HTTP&#x2F;3 first (advertised via an &lt;code&gt;Alt-Svc&lt;&#x2F;code&gt;
header or DNS HTTPS records), and that traffic will be UDP on port 443 --
completely bypassing the TCP redirect rules we set up.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s a question for your tool whether it supports HTTP3 &#x2F; QUIC or not.
For example, &lt;em&gt;mitmproxy&lt;&#x2F;em&gt; since version 11 supports it out of the
box. If you&#x27;re using a tool that supports it, you can just add another rule
to catch UDP traffic and that&#x27;s it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; iptables&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; nat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -A&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; PREROUTING&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; virbr0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; udp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --dport 443 -j&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; REDIRECT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --to-port 8000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But if you&#x27;re using some ancient tool, then one simple fix is to just
block UDP port 443 from the VM entirely, which forces the client to
fall back to HTTP&#x2F;2 or HTTP&#x2F;1.1 over TCP:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# iptables -I FORWARD -i virbr0 -p udp --dport 443 -j REJECT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Using &lt;code&gt;REJECT&lt;&#x2F;code&gt; instead of &lt;code&gt;DROP&lt;&#x2F;code&gt; is friendlier -- it sends an active
ICMP rejection &lt;em&gt;port unreachable&lt;&#x2F;em&gt; message back immediately, so the
client fails fast and falls back to TCP right away, rather than
waiting for a timeout.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ipv6&quot;&gt;IPv6&lt;&#x2F;h2&gt;
&lt;p&gt;If the VM has IPv6 connectivity, don&#x27;t forget that &lt;code&gt;iptables&lt;&#x2F;code&gt; only handles
IPv4. For IPv6 you need &lt;code&gt;ip6tables&lt;&#x2F;code&gt; with the same rules:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# ip6tables -t nat -A PREROUTING -i virbr0 -p tcp --dport 443 -j REDIRECT --to-port 8000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# ip6tables -t nat -A PREROUTING -i virbr0 -p tcp --dport 80  -j REDIRECT --to-port 8000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# ip6tables -I FORWARD -i virbr0 -p udp --dport 443 -j REJECT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In practice, the default libvirt NAT network (&lt;code&gt;virbr0&lt;&#x2F;code&gt;) only does
IPv4, so this may not matter. But if you&#x27;ve configured IPv6 forwarding
on the bridge, or if the VM has a routable IPv6 address through some
other means, or you&#x27;re reading this article in the future, when
libvirt&#x27;s network is IPv6 by default, you&#x27;ll want these rules too --
otherwise the browser will happily use IPv6 to bypass everything you
just set up.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;starting-mitmproxy&quot;&gt;Starting mitmproxy&lt;&#x2F;h2&gt;
&lt;p&gt;Run mitmproxy in transparent mode on the same port:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; mitmproxy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --mode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --listen-host 0.0.0.0 --listen-port 8000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Or, if you prefer a browser-based UI:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; mitmweb&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --mode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; transparent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --listen-host 0.0.0.0 --listen-port 8000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Transparent mode is important here -- it tells mitmproxy that connections are
being redirected to it, and that it should recover the original destination
address from the socket (via &lt;code&gt;SO_ORIGINAL_DST&lt;&#x2F;code&gt;). Without this flag, mitmproxy
would expect a regular explicit proxy connection and everything would fail
immediately.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;trusting-the-ca-certificate-in-windows&quot;&gt;Trusting the CA certificate in Windows&lt;&#x2F;h2&gt;
&lt;p&gt;At this point, traffic from the VM is being redirected through mitmproxy, but
the browser (or any other HTTPS client) will reject the connection because
mitmproxy is presenting its own dynamically-generated certificate, not the real
one from the server. The client doesn&#x27;t trust mitmproxy&#x27;s CA yet.&lt;&#x2F;p&gt;
&lt;p&gt;When mitmproxy starts for the first time, it generates its own CA certificate
and stores it in &lt;code&gt;~&#x2F;.mitmproxy&#x2F;&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;~&#x2F;.mitmproxy&#x2F;mitmproxy-ca.pem        # CA key + cert (keep this private)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;~&#x2F;.mitmproxy&#x2F;mitmproxy-ca-cert.pem   # CA cert only&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;~&#x2F;.mitmproxy&#x2F;mitmproxy-ca-cert.p12   # same, PKCS#12 format (for Windows&#x2F;macOS)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;~&#x2F;.mitmproxy&#x2F;mitmproxy-ca-cert.cer   # same, DER format&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This CA is what mitmproxy uses to sign the per-site certificates it generates
on the fly. For the HTTPS interception to work transparently, the VM must trust
it. You can either copy the certificate file directly from the host, or use the
convenient shortcut mitmproxy provides: from within the Windows VM, open a
browser and navigate to:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;http:&#x2F;&#x2F;mitm.it&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;mitmproxy intercepts this special hostname and serves a page with download
links for its CA certificate on all supported platforms. Download the Windows
version (&lt;code&gt;.p12&lt;&#x2F;code&gt; or the certificate installer), then install it into the
&lt;strong&gt;Trusted Root Certification Authorities&lt;&#x2F;strong&gt; store.&lt;&#x2F;p&gt;
&lt;p&gt;The exact steps in Windows 10:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Double-click the downloaded certificate file.&lt;&#x2F;li&gt;
&lt;li&gt;Select &lt;em&gt;Local Machine&lt;&#x2F;em&gt; and click Next.&lt;&#x2F;li&gt;
&lt;li&gt;Place the certificate in &lt;em&gt;Trusted Root Certification Authorities&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Confirm and finish.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;After that, HTTPS connections from the VM will go through mitmproxy silently
and without certificate errors. You&#x27;ll see all the requests and responses --
headers, bodies, everything -- in mitmproxy&#x27;s interface on the host.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;intercepting-ssl-traffic&#x2F;mitm.png&quot; alt=&quot;mitmproxy in action&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cleaning-up&quot;&gt;Cleaning up&lt;&#x2F;h2&gt;
&lt;p&gt;When you&#x27;re done, remove the rules:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# iptables -t nat -D PREROUTING -i virbr0 -p tcp --dport 443 -j REDIRECT --to-port 8000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# iptables -t nat -D PREROUTING -i virbr0 -p tcp --dport 80  -j REDIRECT --to-port 8000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# iptables -D FORWARD -i virbr0 -p udp --dport 443 -j REJECT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And stop mitmproxy. The Windows CA store will still contain the
mitmproxy certificate, but generally Windows it&#x27;s full of bloat and
trash anyway even (&lt;em&gt;especially&lt;&#x2F;em&gt;) after default fresh install, so that
shouldn&#x27;t matter that much I guess.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;limitations-of-mitmproxy-mitm-approach&quot;&gt;Limitations of mitmproxy &#x2F; MITM approach&lt;&#x2F;h2&gt;
&lt;p&gt;A few things that can trip you up:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Streaming and large responses.&lt;&#x2F;strong&gt; By default, mitmproxy buffers the entire
response body before displaying it. This means long-running connections --
server-sent events, chunked downloads, WebSocket streams -- will appear to hang
in the UI until the transfer finishes, or never complete at all. There is a
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.mitmproxy.org&#x2F;stable&#x2F;overview&#x2F;features&#x2F;#streaming&quot;&gt;streaming mode&lt;&#x2F;a&gt;
that bypasses buffering, but then you lose the ability to inspect the full body.
You can pick your poison I guess.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Certificate pinning.&lt;&#x2F;strong&gt; If the application hardcodes a specific
certificate or public key rather than pulling one from the OS CA
store, it will reject mitmproxy&#x27;s certificate -- regardless of what
you installed in the Windows trust store. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.indusface.com&#x2F;learning&#x2F;what-is-ssl-pinning-a-quick-walk-through&#x2F;&quot;&gt;SSL pinning&lt;&#x2F;a&gt;
exists precisely to prevent what we&#x27;re doing now: a man-in-the-middle
intercepting encrypted traffic. This is common in mobile apps and some
Electron apps. There is no clean workaround; you have to patch the
binary, for example using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;frida.re&quot;&gt;Frida&lt;&#x2F;a&gt;, which lets you hook into a
running process and disable the pinning check at runtime. How to disable
this check varies between the apps, because you need to patch the
code, but there are Frida scripts that automate this for popular systems,
all you need to do is to search for them.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Per-application CA stores.&lt;&#x2F;strong&gt; Some apps don&#x27;t use the Windows
certificate store at all. Firefox ships with its own, Java uses a
bundled &lt;code&gt;cacerts&lt;&#x2F;code&gt; keystore -- you can add the mitmproxy CA to it with
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.ibm.com&#x2F;docs&#x2F;en&#x2F;webmethods-integration&#x2F;wm-my-webmethods-server&#x2F;10.11.0?topic=client-importing-ca-certificates&quot;&gt;&lt;code&gt;keytool&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; -- and some Go or Rust binaries embed
Mozilla&#x27;s CA bundle directly. For these, you need to import the
mitmproxy CA separately into whatever store the app actually reads.&lt;&#x2F;p&gt;
&lt;p&gt;Happy sniffing!&lt;&#x2F;p&gt;
&lt;p&gt;G.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fixing: Vivaldi opens Nautilus instead of Dolphin on KDE</title>
        <published>2026-03-22T00:00:00+00:00</published>
        <updated>2026-03-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/vivaldi-opens-nautilus-on-kde/"/>
        <id>https://anadoxin.org/blog/vivaldi-opens-nautilus-on-kde/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/vivaldi-opens-nautilus-on-kde/">&lt;p&gt;If you&#x27;re on KDE with both Dolphin and Nautilus installed, you may have noticed
that clicking &lt;em&gt;Open containing folder&lt;&#x2F;em&gt; in Vivaldi (or any Chromium-based
browser, really) opens Nautilus instead of Dolphin. Everything else seems fine
-- &lt;code&gt;xdg-mime query default inode&#x2F;directory&lt;&#x2F;code&gt; returns &lt;code&gt;org.kde.dolphin.desktop&lt;&#x2F;code&gt;,
and KDE system settings agree. Yet there&#x27;s the GNOME devs, pushing you their
stack even if you don&#x27;t want it.&lt;&#x2F;p&gt;
&lt;p&gt;One obvious way would be to get rid of GNOME, and I&#x27;d argue that would make the
most sense. However, if you want to leave it, maybe just because we need to know
our enemies, then read on.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;root-cause&quot;&gt;Root cause&lt;&#x2F;h2&gt;
&lt;p&gt;The key point is that when a browser wants to open a containing
directory in the file manager, it doesn&#x27;t call &lt;code&gt;xdg-open&lt;&#x2F;code&gt;. Instead, it
calls the &lt;code&gt;ShowItems&lt;&#x2F;code&gt; method on the &lt;code&gt;org.freedesktop.FileManager1&lt;&#x2F;code&gt;
D-Bus service.&lt;&#x2F;p&gt;
&lt;p&gt;The problem is that both Dolphin and Nautilus ship a D-Bus service file that
claims this name:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Nautilus:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;usr&#x2F;share&#x2F;dbus-1&#x2F;services&#x2F;org.freedesktop.FileManager1.service&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Dolphin:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;usr&#x2F;share&#x2F;dbus-1&#x2F;services&#x2F;org.kde.dolphin.FileManager1.service&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Both files contain &lt;code&gt;Name=org.freedesktop.FileManager1&lt;&#x2F;code&gt;. When the service isn&#x27;t
already running, D-Bus auto-activates one of them. It picks up
&lt;code&gt;org.freedesktop.FileManager1.service&lt;&#x2F;code&gt; first -- because it comes first
alphabetically -- and launches Nautilus.&lt;&#x2F;p&gt;
&lt;p&gt;You can verify this by checking the two files:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;cat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &#x2F;usr&#x2F;share&#x2F;dbus-1&#x2F;services&#x2F;org.freedesktop.FileManager1.service&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# Exec=&#x2F;usr&#x2F;bin&#x2F;nautilus --gapplication-service&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;cat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &#x2F;usr&#x2F;share&#x2F;dbus-1&#x2F;services&#x2F;org.kde.dolphin.FileManager1.service&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# Exec=&#x2F;usr&#x2F;bin&#x2F;dolphin --daemon&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;the-fix&quot;&gt;The fix&lt;&#x2F;h2&gt;
&lt;p&gt;D-Bus checks &lt;code&gt;$XDG_DATA_HOME&#x2F;dbus-1&#x2F;services&#x2F;&lt;&#x2F;code&gt; before the system-level
directories. So creating a user-level override is enough:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;mkdir&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; ~&#x2F;.local&#x2F;share&#x2F;dbus-1&#x2F;services&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;cat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; ~&#x2F;.local&#x2F;share&#x2F;dbus-1&#x2F;services&#x2F;org.freedesktop.FileManager1.service&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;#39;EOF&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;[D-BUS Service]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;Name=org.freedesktop.FileManager1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;Exec=&#x2F;usr&#x2F;bin&#x2F;dolphin --daemon&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;EOF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s the persistent fix. It survives reboots without touching any system
files.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;if-it-still-doesn-t-work-after-creating-the-file&quot;&gt;If it still doesn&#x27;t work after creating the file&lt;&#x2F;h2&gt;
&lt;p&gt;The service file only matters when the &lt;code&gt;org.freedesktop.FileManager1&lt;&#x2F;code&gt; name is
not yet claimed on the session bus. If Nautilus is already running and holding
that name, D-Bus won&#x27;t re-activate anything -- it&#x27;ll just keep routing calls to
the existing Nautilus instance.&lt;&#x2F;p&gt;
&lt;p&gt;Kill it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;pkill&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;nautilus --gapplication-service&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After that, the next time Vivaldi triggers &lt;em&gt;Show in folder&lt;&#x2F;em&gt;, D-Bus will activate
Dolphin using your new service file.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;confirming-it-works&quot;&gt;Confirming it works&lt;&#x2F;h2&gt;
&lt;p&gt;You can test the whole thing without opening a browser at all:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;pkill&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;nautilus --gapplication-service&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;pkill&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;dolphin --daemon&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;dbus-send&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --session --print-reply \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;  --dest=org.freedesktop.FileManager1 \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;  &#x2F;org&#x2F;freedesktop&#x2F;FileManager1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;  org.freedesktop.FileManager1.ShowItems&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;  array:string:&amp;quot;file:&#x2F;&#x2F;&#x2F;tmp&amp;quot; string:&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Dolphin should open. If Nautilus opens, double-check the service file contents
and path.&lt;&#x2F;p&gt;
&lt;p&gt;If that&#x27;ll work, you still have some work to do. Figuring out why you
still have GNOME is a non trivial task. I&#x27;m still working on it.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fixing: `Could not access KVM kernel module`</title>
        <published>2026-03-16T00:00:00+00:00</published>
        <updated>2026-03-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/wrong-kvm-permissions/"/>
        <id>https://anadoxin.org/blog/wrong-kvm-permissions/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/wrong-kvm-permissions/">&lt;p&gt;Maybe you&#x27;ve seen this error, when you sometimes use &lt;code&gt;virt-manager&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Error starting domain: internal error: process exited while connecting to monitor:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;qemu-system-x86_64: -accel kvm: Could not access KVM kernel module: No such file or directory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;qemu-system-x86_64: -accel kvm: failed to initialize kvm: No such file or directory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;it sounds like something is pretty broken. Potential problems include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;KVM module is missing,&lt;&#x2F;li&gt;
&lt;li&gt;virtualization is disabled in BIOS,&lt;&#x2F;li&gt;
&lt;li&gt;or &lt;code&gt;&#x2F;dev&#x2F;kvm&lt;&#x2F;code&gt; does not exist due to missing support from the OS.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;But there is another subtle cause: &lt;code&gt;&#x2F;dev&#x2F;kvm&lt;&#x2F;code&gt; is created with wrong ownership&#x2F;permissions because the &lt;code&gt;kvm&lt;&#x2F;code&gt; group is not treated as a system group by &lt;code&gt;udev&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This short blog post will dig through a solution to this problem.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-problem&quot;&gt;The problem&lt;&#x2F;h2&gt;
&lt;p&gt;On an affected host, checks often look like this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;lsmod | grep kvm&lt;&#x2F;code&gt; shows &lt;code&gt;kvm&lt;&#x2F;code&gt; and &lt;code&gt;kvm_intel&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;kvm_amd&lt;&#x2F;code&gt; loaded.&lt;&#x2F;li&gt;
&lt;li&gt;CPU supports virtualization (&lt;code&gt;vmx&lt;&#x2F;code&gt; or &lt;code&gt;svm&lt;&#x2F;code&gt; exists in &lt;code&gt;&#x2F;proc&#x2F;cpuinfo&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;&#x2F;dev&#x2F;kvm&lt;&#x2F;code&gt; exists, but is owned by &lt;code&gt;root:root&lt;&#x2F;code&gt; and often mode &lt;code&gt;0600&lt;&#x2F;code&gt;:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;crw------- 1 root root ... &#x2F;dev&#x2F;kvm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;journalctl -u systemd-udevd&lt;&#x2F;code&gt; may contain:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Failed to resolve group &amp;#39;kvm&amp;#39; ... Not a system group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That line is the key. &quot;Not a system group&quot; tells you exactly what is happening.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;root-cause&quot;&gt;Root cause&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;udev&lt;&#x2F;code&gt; rules (for example in &lt;code&gt;&#x2F;usr&#x2F;lib&#x2F;udev&#x2F;rules.d&#x2F;50-udev-default.rules&lt;&#x2F;code&gt;) typically expect:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;KERNEL==&amp;quot;kvm&amp;quot;, GROUP=&amp;quot;kvm&amp;quot;, MODE=&amp;quot;0666&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If your &lt;code&gt;kvm&lt;&#x2F;code&gt; group &lt;strong&gt;has a GID outside the system range&lt;&#x2F;strong&gt; (commonly above &lt;code&gt;SYS_GID_MAX&lt;&#x2F;code&gt; from &lt;code&gt;&#x2F;etc&#x2F;login.defs&lt;&#x2F;code&gt;), then &lt;strong&gt;group resolution can fail during device setup&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;When that happens, &lt;code&gt;&#x2F;dev&#x2F;kvm&lt;&#x2F;code&gt; may &lt;em&gt;fall back&lt;&#x2F;em&gt; to &lt;code&gt;root:root&lt;&#x2F;code&gt; and restrictive permissions, and QEMU launched by libvirt fails to initialize KVM.&lt;&#x2F;p&gt;
&lt;p&gt;So the problem is not that &lt;code&gt;&#x2F;dev&#x2F;kvm&lt;&#x2F;code&gt; has wrong permissions, but rather that the chosen group has wrong ID (outside of the SYS_GID range).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;verification&quot;&gt;Verification&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# 1) Device ownership&#x2F;mode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;ls&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &#x2F;dev&#x2F;kvm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# 2) KVM modules&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;lsmod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; grep&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -E&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;#39;kvm|kvm_intel|kvm_amd&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# 3) Group + GID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;getent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; group kvm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# 4) System group range&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;grep&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -E&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;#39;^(SYS_GID_MIN|SYS_GID_MAX)&amp;#39; &#x2F;etc&#x2F;login.defs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# 5) udev hint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;journalctl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -u&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; systemd-udevd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --no-pager&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; grep&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;#39;Failed to resolve group.*kvm&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If &lt;code&gt;&#x2F;dev&#x2F;kvm&lt;&#x2F;code&gt; is &lt;code&gt;root:root&lt;&#x2F;code&gt; and logs mention “Not a system group”, this guide applies.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;temporary-workaround-until-reboot&quot;&gt;Temporary workaround (until reboot)&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; chgrp kvm &#x2F;dev&#x2F;kvm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; chmod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0660&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &#x2F;dev&#x2F;kvm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then retry VM start.&lt;&#x2F;p&gt;
&lt;p&gt;This will simply give access to &lt;code&gt;&#x2F;dev&#x2F;kvm&lt;&#x2F;code&gt; for everyone from the &lt;code&gt;kvm&lt;&#x2F;code&gt; group (you should be included).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;permanent-fix&quot;&gt;Permanent fix&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Move &lt;code&gt;kvm&lt;&#x2F;code&gt; to a free &lt;strong&gt;system GID&lt;&#x2F;strong&gt; (inside &lt;code&gt;SYS_GID_MIN..SYS_GID_MAX&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;Reload&#x2F;trigger udev (or reboot).&lt;&#x2F;li&gt;
&lt;li&gt;Restart libvirt.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; groupmod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -g 78&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; kvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;    # be sure that 78 is not allocated to a group on your system&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; udevadm control&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --reload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; udevadm trigger&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --name-match=&#x2F;dev&#x2F;kvm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; systemctl restart libvirtd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After that:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;ls&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -l&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &#x2F;dev&#x2F;kvm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# expected: root kvm and mode usable for qemu&#x2F;libvirt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;a-bash-script-that-fixes-the-problem&quot;&gt;A bash script that fixes the problem&lt;&#x2F;h2&gt;
&lt;p&gt;I prepared a script that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;validates prerequisites,&lt;&#x2F;li&gt;
&lt;li&gt;finds a free system GID,&lt;&#x2F;li&gt;
&lt;li&gt;optionally updates &lt;code&gt;kvm&lt;&#x2F;code&gt; group GID,&lt;&#x2F;li&gt;
&lt;li&gt;reloads udev,&lt;&#x2F;li&gt;
&lt;li&gt;fixes &lt;code&gt;&#x2F;dev&#x2F;kvm&lt;&#x2F;code&gt;,&lt;&#x2F;li&gt;
&lt;li&gt;restarts libvirt,&lt;&#x2F;li&gt;
&lt;li&gt;prints final diagnostics.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;See: &lt;a href=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;wrong-kvm-permissions&#x2F;fix-kvm-group.sh&quot;&gt;fix-kvm-group.sh&lt;&#x2F;a&gt;. Remember to inspect the script yourself before running. Make sure it&#x27;s safe.&lt;&#x2F;p&gt;
&lt;p&gt;Run it as root:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; bash .&#x2F;fix-kvm-group.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Optional dry run:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; bash .&#x2F;fix-kvm-group.sh&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --dry-run&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;takeaway&quot;&gt;Takeaway&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Always check &lt;code&gt;systemd-udevd&lt;&#x2F;code&gt; logs when &lt;code&gt;&#x2F;dev&#x2F;*&lt;&#x2F;code&gt; ownership looks wrong.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If you maintain a podman image or something similar, ensure &lt;code&gt;kvm&lt;&#x2F;code&gt; is provisioned as a &lt;strong&gt;system group&lt;&#x2F;strong&gt; from the start.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Standard actions of Linux package managers</title>
        <published>2023-02-25T00:00:00+00:00</published>
        <updated>2023-02-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/linux-package-managers.html/"/>
        <id>https://anadoxin.org/blog/linux-package-managers.html/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/linux-package-managers.html/">&lt;p&gt;I keep forgetting the command line options for standard Linux package
manager actions, so I&#x27;ve decided to write a blog post about it. I&#x27;m
currently using Gentoo, ArchLinux and Fedora, so I&#x27;ll include pacman, rpm
and deb flavors (for completion).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;q-locating-the-owner-package-of-a-specified-file&quot;&gt;Q: Locating the owner package of a specified file&lt;&#x2F;h1&gt;
&lt;p&gt;Portage:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ qfile &#x2F;usr&#x2F;bin&#x2F;ls    # or &amp;#39;equery b &#x2F;usr&#x2F;bin&#x2F;ls&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sys-apps&#x2F;coreutils: &#x2F;usr&#x2F;bin&#x2F;ls&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Pacman:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ pacman -Qo &#x2F;usr&#x2F;bin&#x2F;ls&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;usr&#x2F;bin&#x2F;ls is owned by coreutils 9.1-3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;dpkg:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ dpkg -S lspci&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pciutils: &#x2F;usr&#x2F;bin&#x2F;lspci&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;rpm:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ rpm -qf &#x2F;usr&#x2F;bin&#x2F;ps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;procps-ng-3.3.17-4.fc36.1.x86_64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h1 id=&quot;q-listing-the-contents-of-selected-package&quot;&gt;Q: Listing the contents of selected package&lt;&#x2F;h1&gt;
&lt;p&gt;Portage:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;qlist coreutils       # or &amp;#39;equery f coreutils&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Pacman:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ pacman -Ql coreutils&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;dpkg:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ dpkg -L coreutils&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;rpm:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ rpm -ql procps-ng&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h1 id=&quot;q-dump-information-about-a-package&quot;&gt;Q: Dump information about a package&lt;&#x2F;h1&gt;
&lt;p&gt;Portage:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ emerge --search coreutils&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;or&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ vim `equery w coreutils`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Pacman:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ pacman -Qi coreutils&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;dpkg:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ dpkg -s coreutils&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;rpm:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ rpm -qi coreutils&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I&#x27;m not delusional enough to expect that I&#x27;ll remember this, but at least
now I&#x27;ll have a one-stop place where I can quickly look this up.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Creating ssh proxies</title>
        <published>2022-07-08T00:00:00+00:00</published>
        <updated>2022-07-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/sshd-proxies/"/>
        <id>https://anadoxin.org/blog/sshd-proxies/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/sshd-proxies/">&lt;p&gt;I always forget what are the proper arguments to create a ssh proxy in some specific way, so I&#x27;m leaving a small cheatsheet here for my future references. I&#x27;ve &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;defeating-nat-with-reverse-ssh-proxies.html&quot;&gt;already written&lt;&#x2F;a&gt; a blog post about it a few years ago, but now I need a fast reference instead of a descriptive blog post.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;example-1-ssh-l&quot;&gt;Example 1 (ssh -L)&lt;&#x2F;h3&gt;
&lt;p&gt;There&#x27;s a VM (&lt;code&gt;heravm&lt;&#x2F;code&gt;) running on my MacMini (&lt;code&gt;hera&lt;&#x2F;code&gt;) which doesn&#x27;t have access to the Internet, only has network access to the host machine. I want to connect to SSH service on this VM, but I want to do it from my desktop instead of MacMini. The desktop machine is in the same network as MacMini (although it doesn&#x27;t really matter).&lt;&#x2F;p&gt;
&lt;p&gt;I can issue this command from the &lt;code&gt;&amp;lt;desktop&amp;gt;&lt;&#x2F;code&gt; machine:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;desktop$ ssh -Nf -L 7722:&amp;lt;heravm&amp;gt;:22 &amp;lt;hera&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will open port &lt;code&gt;7722&lt;&#x2F;code&gt; on the &lt;code&gt;L&lt;&#x2F;code&gt;ocal machine (&lt;code&gt;desktop&lt;&#x2F;code&gt;). When connecting to &lt;code&gt;localhost:7722&lt;&#x2F;code&gt; from my desktop, ssh will connect to &lt;code&gt;&amp;lt;hera&amp;gt;:22&lt;&#x2F;code&gt;, and then it will forward all traffic from &lt;code&gt;&amp;lt;hera&amp;gt;:22&lt;&#x2F;code&gt; to &lt;code&gt;&amp;lt;heravm&amp;gt;:22&lt;&#x2F;code&gt;. So make sure the &lt;code&gt;heravm&lt;&#x2F;code&gt; is reachable from &lt;code&gt;hera&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;example-2-ssh-r&quot;&gt;Example 2 (ssh -R)&lt;&#x2F;h3&gt;
&lt;p&gt;There&#x27;s a VM (&lt;code&gt;heravm&lt;&#x2F;code&gt;) running on my MacMini (&lt;code&gt;hera&lt;&#x2F;code&gt;) which doesn&#x27;t have access to the Internet, but has network access to the host machine. I want to connect to this VM from another house (so, from a different network). I have a VPS server &lt;code&gt;ostarion&lt;&#x2F;code&gt; with a public IP reachable from both networks that can help with NAT traversal.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hera$ ssh -Nf -R 12345:&amp;lt;heravm&amp;gt;:22 &amp;lt;ostarion&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will open port 12345 on the &lt;code&gt;R&lt;&#x2F;code&gt;emote machine &lt;code&gt;&amp;lt;ostarion&amp;gt;&lt;&#x2F;code&gt;. After relocating to another house and connecting to &lt;code&gt;&amp;lt;ostarion&amp;gt;:12345&lt;&#x2F;code&gt;, I will effectively connect to &lt;code&gt;&amp;lt;heravm&amp;gt;:22&lt;&#x2F;code&gt;, so directly onto the VM that has no Internet access.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;example-3-ssh-d&quot;&gt;Example 3 (ssh -D)&lt;&#x2F;h3&gt;
&lt;p&gt;I have a VPS &lt;code&gt;ostarion&lt;&#x2F;code&gt;. I would like to browse the web so that websites will think I&#x27;m browsing from &lt;code&gt;ostarion&lt;&#x2F;code&gt; instead of my local ISP.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;desktop$ ssh -D8080 &amp;lt;ostarion&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will create a SOCKS5 server on host &lt;code&gt;0.0.0.0:8080&lt;&#x2F;code&gt;. Use browser plugins like SwitchyOmega to use this proxy for chosen websites.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;persistence&quot;&gt;Persistence&lt;&#x2F;h3&gt;
&lt;p&gt;Temporary tunnels are fun, but persistent tunnels that spawn automatically and restart on network failures are what we&#x27;re after. It&#x27;s still a matter of empirical verification, but one persistence method is described below.&lt;&#x2F;p&gt;
&lt;p&gt;The example scenario I&#x27;m trying to accomplish is this: there&#x27;s a virtual machine &lt;code&gt;heravm&lt;&#x2F;code&gt; running on some host (&lt;code&gt;hera&lt;&#x2F;code&gt;) that is behind NAT. I want to be able to connect to this VM from another house. I can use an external VPS that I control (&lt;code&gt;ostarion&lt;&#x2F;code&gt;) to setup ssh tunelling. The &lt;code&gt;heravm&lt;&#x2F;code&gt; VM doesn&#x27;t have Internet connection enabled, it&#x27;s just able to connect to its host (&lt;code&gt;hera&lt;&#x2F;code&gt;) and nothing else.&lt;&#x2F;p&gt;
&lt;p&gt;This basically means that I need to create reverse tunneling from &lt;code&gt;hera&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hera$ ssh -R 12345:&amp;lt;heravm&amp;gt;:22 ostarion&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This means that when I connect to &lt;code&gt;&amp;lt;ostarion&amp;gt;:12345&lt;&#x2F;code&gt;, I will effectively connect to &lt;code&gt;&amp;lt;heravm&amp;gt;:22&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Now we need to make sure that this tunnel will be created for as long as it&#x27;s possible, and will be re-created when the machine will be restarted from some reason (e.g. power failure).&lt;&#x2F;p&gt;
&lt;h4 id=&quot;persistence-on-macos-tested-on-monterey&quot;&gt;Persistence on macOS (tested on Monterey)&lt;&#x2F;h4&gt;
&lt;p&gt;We&#x27;re gonna utilise launchd to manage our tunnel. The tunnel will be (re)started when needed.&lt;&#x2F;p&gt;
&lt;p&gt;But first, we&#x27;re going to create a new ssh identity (a private and a public key) that won&#x27;t use any password. If that sounds like a security risk, then I agree, but the proper solution for this depends entirely on your setup, and is out of scope for this blog post.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Remember to NOT overwrite your main identity!&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hera $ ssh-keygen -t ecdsa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Generating public&#x2F;private ecdsa key pair.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enter file in which to save the key (&#x2F;home&#x2F;antek&#x2F;.ssh&#x2F;id_ecdsa): &#x2F;path&#x2F;to&#x2F;unattended&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enter passphrase (empty for no passphrase):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enter same passphrase again:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Your identification has been saved in &#x2F;path&#x2F;to&#x2F;unattended&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Your public key has been saved in &#x2F;path&#x2F;to&#x2F;unattended.pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;The key fingerprint is:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHA256:xPB9hGEfqxhI2041ioN7urHxYt2rtQEAmvuOsArGDdA antek@host&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;The key&amp;#39;s randomart image is:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+---[ECDSA 256]---+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  .   o   =oo    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| + . o O =.+ o   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|+ E o = O . +    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|..   o = o o     |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|..  . o S .      |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|..o  o .         |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|oo..+. .o        |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|++  o*...o       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|= ..o.o.o.       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+----[SHA256]-----+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Make sure to remove &lt;em&gt;group&lt;&#x2F;em&gt; and &lt;em&gt;other&lt;&#x2F;em&gt; read rights from &lt;code&gt;&#x2F;path&#x2F;to&#x2F;unattended&lt;&#x2F;code&gt; file, so that only the owner will be able to access the private key.&lt;&#x2F;p&gt;
&lt;p&gt;Having an &quot;unattended&quot; private key created we can create a new ssh configuration entry inside &lt;code&gt;~&#x2F;.ssh&#x2F;config&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;host host_unattended&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    hostname $hostname$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    user antek&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    identityfile &#x2F;path&#x2F;to&#x2F;unattended&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    identitiesonly yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;strong&gt;$hostname$&lt;&#x2F;strong&gt; variable points to an external server that is always on, has a publicly reachable IP address and of course it&#x27;s running sshd (e.g. a VPS).&lt;&#x2F;p&gt;
&lt;p&gt;After the ssh config is ready, we can proceed with creation of the new launchd descriptor for our service (named &lt;code&gt;servicename.plist&lt;&#x2F;code&gt;):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;xml&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; version&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;1.0&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; encoding&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;UTF-8&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;?&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;DOCTYPE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; plist&lt;&#x2F;span&gt;&lt;span&gt; PUBLIC &amp;quot;-&#x2F;&#x2F;Apple&#x2F;&#x2F;DTD PLIST 1.0&#x2F;&#x2F;EN&amp;quot; &amp;quot;http:&#x2F;&#x2F;www.apple.com&#x2F;DTDs&#x2F;PropertyList-1.0.dtd&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;plist&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; version&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;1.0&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;dict&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;Label&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;org.anadoxin.servicename&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;username&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;$username$&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;   &amp;lt;!-- HERE --&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;groupname&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;staff&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;ProgramArguments&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;array&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&#x2F;usr&#x2F;bin&#x2F;ssh&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;-R 12345:$heravm$:22&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;   &amp;lt;!-- HERE --&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;-NTC&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;-o ExitOnForwardFailure=yes&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;-o ServerAliveInterval=60&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;-o ServerAliveCountMax=10&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;host_unattended&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;array&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;StandardErrorPath&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&#x2F;tmp&#x2F;org.anadoxin.servicename.stderr&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;StandardOutPath&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&#x2F;tmp&#x2F;org.anadoxin.servicename.stdout&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;RunAtLoad&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;KeepAlive&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;dict&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #22863A;&quot;&gt;plist&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Make sure you notice the &lt;strong&gt;$heravm$&lt;&#x2F;strong&gt; and &lt;strong&gt;$username$&lt;&#x2F;strong&gt; variables! Change them according to your requirements. You should probably change the &lt;strong&gt;org.anadoxin.servicename&lt;&#x2F;strong&gt; as well.&lt;&#x2F;p&gt;
&lt;p&gt;In the example above, the ssh binary is called with the following options:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;-N&lt;&#x2F;strong&gt; -- don&#x27;t execute any command. This option is used often when forwarding ports (so, perfect for our case),&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;-T&lt;&#x2F;strong&gt; -- disables pseudo-terminal allocation (no point if we&#x27;re not spawning any interactive sessions),&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;-C&lt;&#x2F;strong&gt; -- enable data compression -- useful only for slow links. Disable if you have fast Internet connection.&lt;&#x2F;li&gt;
&lt;li&gt;Remember to &lt;em&gt;NOT&lt;&#x2F;em&gt; use the &lt;strong&gt;-f&lt;&#x2F;strong&gt; flag here. This flag will fork ssh to the background. Normally this would be useful, but used in this descriptor it will confuse launchd; it will think that sshd has exited, and will try to start it again (over and over again).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;After the launchd descriptor has been created, it can be started with &lt;code&gt;launchctl&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hera$ sudo launchctl load servicename.plist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you&#x27;re getting errors, please verify that the syntax of the XML file is OK (&lt;code&gt;plutil -p servicename.plist&lt;&#x2F;code&gt;), the access rights are not too loose, and inspect both stderr and stdout streams created in &lt;code&gt;&#x2F;tmp&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Because the descriptor uses &lt;code&gt;RunAtLoad=true&lt;&#x2F;code&gt;, it should be executed on load. Verify the tunnel is working by e.g. using &lt;code&gt;ps&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hera$ ps aux | grep &amp;quot;&#x2F;usr&#x2F;bin&#x2F;ssh&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;antek             5011   0.1  0.0 408667760   5472   ??  Ss    8:31PM   0:00.23 &#x2F;usr&#x2F;bin&#x2F;ssh -R 12345:192.168.64.2:22 -NTC -o ExitOnForwardFailure=yes -o ServerAliveInterval=60 -o ServerAliveCountMax=10 ostarion_unattended&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If from any reason the tunnel will collapse (e.g. network failure, power failure), it should be automatically re-created by launchd.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;notes&quot;&gt;Notes&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;-L&lt;&#x2F;code&gt;, &lt;code&gt;-R&lt;&#x2F;code&gt; and &lt;code&gt;-D&lt;&#x2F;code&gt; switches accept also the &lt;code&gt;listening interface&lt;&#x2F;code&gt;. Default listening interface settings open up the port for everyone (binding the socket to &lt;code&gt;0.0.0.0&lt;&#x2F;code&gt;). This may not be what you want, and you might limit the bind address to &lt;code&gt;127.0.0.1&lt;&#x2F;code&gt;. So, for &quot;example 3&quot;, the more secure command would be:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ ssh -D 127.0.0.1:8080 &amp;lt;ostarion&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can find the proper syntax for all options in &lt;code&gt;man ssh&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Sniffing HTTPS during development</title>
        <published>2022-01-28T00:00:00+00:00</published>
        <updated>2022-01-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/2022-01-28-sniffing-ssl-during-development/inspecting-encrypted-traffic-during-development/"/>
        <id>https://anadoxin.org/blog/2022-01-28-sniffing-ssl-during-development/inspecting-encrypted-traffic-during-development/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/2022-01-28-sniffing-ssl-during-development/inspecting-encrypted-traffic-during-development/">&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;When programming, developer sometimes needs to contact a server, use API, etc.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;HTTPS is now a must. Letsencrypt makes it easy. There are several frameworks for easy HTTPS communication.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Libs are high-level. They are easy to use, but they sometimes do some of the work behind the scenes.
This sometimes makes it difficult to know what exactly is being sent and how. Sometimes we need to check
if a header is being sent. Sometimes there are bugs in libraries, or non-intuitive uses (e.g. httpclient
in esetctl).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;HTTP would make it easy. We would need to use Wireshark and that&#x27;s it, we have full communication recorded.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;But we&#x27;re using HTTPS, so we can&#x27;t simply sniff TLS traffic.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;First option: SSLKEYLOGFILE -- per library support. curl&#x2F;libcurl supports it, java doesn&#x27;t. This means that
it&#x27;s a de-facto standard, and support is pretty spotty.&lt;&#x2F;p&gt;
&lt;p&gt;BURP potrafi sniffowac ssl?&lt;&#x2F;p&gt;
&lt;p&gt;Second option: mitmproxy&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Removing the unwanted Konsole toolbar</title>
        <published>2021-07-19T00:00:00+00:00</published>
        <updated>2021-07-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/removing-unwanted-konsole-toolbar/"/>
        <id>https://anadoxin.org/blog/removing-unwanted-konsole-toolbar/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/removing-unwanted-konsole-toolbar/">&lt;p&gt;Generally I&#x27;m pretty happy with my KDE desktop, although I&#x27;m among those people who think that KDE hasn&#x27;t been the same since version 3. Having version KDE v5.22.3 currently installed on my machine I do see lots of bugs, but the advantages like the feature list, and not assuming the user is an idiot (comparing to GNOME) easily convinces me that KDE is the best thing Linux Desktop has to offer for me (I also refuse to use the &lt;em&gt;Plasma&lt;&#x2F;em&gt; terminology, because I&#x27;m still not sure what is it).&lt;&#x2F;p&gt;
&lt;p&gt;That being said, some bugs are pretty frustrating. One of the bugs that has popped up recently is a Konsole bug that doesn&#x27;t allow the user to hide its toolbar. Normally I do mind when I see some pixels that are out of place, and in this particular case a whole toolbar is out of place, so I couldn&#x27;t continue until I&#x27;ve found a solution. I considered switching to a different distro because of it, but ultimately I didn&#x27;t have to because of a quick walkaround.&lt;&#x2F;p&gt;
&lt;p&gt;Normally this bug is active on my openSUSE distribution, but I don&#x27;t see it under ArchLinux. This is how it looks like on openSUSE:&lt;&#x2F;p&gt;
&lt;iframe id=&quot;lbry-iframe&quot; width=&quot;560&quot; height=&quot;315&quot; src=&quot;https:&#x2F;&#x2F;odysee.com&#x2F;$&#x2F;embed&#x2F;kdebugtoolbar&#x2F;094fbb622d2703ae23d2b2b87d04e511e12a1a8e?r=81kN71SLKx4R2C87CPREVjiHftowkCzm&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;
&lt;p&gt;(the video shows a toolbar that can&#x27;t be hidden)&lt;&#x2F;p&gt;
&lt;p&gt;Lucky users (on e.g. ArchLinux) have these options to their disposal, freeing them from this problem:&lt;&#x2F;p&gt;
&lt;!--image shortcode magic--&gt;
&lt;img alt=&quot;Screenshot on ArchLinux&quot; src=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;removing-unwanted-konsole-toolbar&#x2F;arch.png&quot; class=&quot;zoomable&quot; data-background=&quot;var(--col-bg)&quot;&#x2F;&gt;
&lt;p&gt;The problem is that some distributions bundle KDE in a way that this option is simply not available, as shown in the video.&lt;&#x2F;p&gt;
&lt;p&gt;So, the first workaround I&#x27;ve found is:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Ensure that the menu bar is visible (Ctrl+Shift+M),&lt;&#x2F;li&gt;
&lt;li&gt;Right-click on the menu bar,&lt;&#x2F;li&gt;
&lt;li&gt;Hide the toolbar from there,&lt;&#x2F;li&gt;
&lt;li&gt;Hide the menu bar again (if needed).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This &lt;em&gt;does&lt;&#x2F;em&gt; hide the toolbar, but the problem is that this method won&#x27;t work in another instance of Konsole. So it fixes the problem only for current Konsole window.&lt;&#x2F;p&gt;
&lt;p&gt;Another workaround, which might be better, is to open this configuration file:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;~&#x2F;.local&#x2F;share&#x2F;kxmlgui5&#x2F;konsole&#x2F;konsoleui.rc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and comment out this section inside it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;!--&amp;lt;ToolBar name=&amp;quot;mainToolBar&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;lt;text&amp;gt;Main Toolbar&amp;lt;&#x2F;text&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;lt;index&amp;gt;0&amp;lt;&#x2F;index&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;lt;Action name=&amp;quot;new-tab&amp;quot;&#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;lt;Action name=&amp;quot;split-view-left-right&amp;quot;&#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;lt;Action name=&amp;quot;split-view-top-bottom&amp;quot;&#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&#x2F;ToolBar&amp;gt;--&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This effectively hides the toolbar, maybe not in the best way possible, but it appears to work! At least maybe until some update will show up that properly fixes the problem, or someone else will figure out a better solution.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Usage of encrypted file containers</title>
        <published>2014-11-09T00:00:00+00:00</published>
        <updated>2014-11-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/usage-of-encrypted-file-containers.html/"/>
        <id>https://anadoxin.org/blog/usage-of-encrypted-file-containers.html/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/usage-of-encrypted-file-containers.html/">&lt;p&gt;Lots of modern systems (Linux, BSDs) support encryption of block devices, or
file containers, in a similar way that TrueCrypt does it. It is basically (more
or less) a built-in TrueCrypt that gives you the possibility to build a secure
medium and store your sensitive files inside.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;device-mapper&quot;&gt;Device-mapper&lt;&#x2F;h2&gt;
&lt;p&gt;There is a subsystem in the Linux kernel called &lt;code&gt;device-mapper&lt;&#x2F;code&gt;. It allows the
creation of arbitrary devices that are controlled by software applications.
This means that if &lt;code&gt;device-mapper&lt;&#x2F;code&gt; creates a file, its content is being served
by another program, not the filesystem module like it&#x27;s done with conventional
files.&lt;&#x2F;p&gt;
&lt;p&gt;This, in turn, means that &lt;code&gt;device-mapper&lt;&#x2F;code&gt; allows to create &quot;dynamic&quot; files
(these are actually &#x27;devices&#x27;, but on Linux there&#x27;s not a big functional
difference between those two). The content of these files are being generated
during a read request. It&#x27;s a very handy mechanism for on-demand file
decryption: if a program tries to read an encrypted file, the software driver
that controls this file&#x27;s contents (via &lt;code&gt;device-mapper&lt;&#x2F;code&gt;) reads the encrypted
content from the disk, decrypts it, and serves decrypted data to requesting
application. No plaintext is ever written to the disk.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;device-mapper-stacking&quot;&gt;Device-mapper stacking&lt;&#x2F;h2&gt;
&lt;p&gt;One of the nicest features of &lt;code&gt;device-mapper&lt;&#x2F;code&gt; is the ability to stack with
itself. Consider this example:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;usage-of-encrypted-file-containers.html&#x2F;devicemapper1.png&quot; alt=&quot;Flowchart 1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In theory, it&#x27;s possible to create a &lt;code&gt;device-mapper&lt;&#x2F;code&gt; device (so: a &#x27;virtual
device&#x27;) that will generate unlimited amount of &lt;code&gt;NULL&lt;&#x2F;code&gt; bytes on read request --
in similar fashion that it is done with the &lt;code&gt;&#x2F;dev&#x2F;null&lt;&#x2F;code&gt; device.&lt;&#x2F;p&gt;
&lt;p&gt;It is also possible to create another device, an &#x27;xor virtual device&#x27; that reads
data from its input file, XORs them with &lt;code&gt;0xA1&lt;&#x2F;code&gt;, and emits the output. This is
different from &lt;code&gt;&#x2F;dev&#x2F;null&lt;&#x2F;code&gt;, because in this case the device needs another device
to be able to read data from it, perform some manipulation, and output altered
data.&lt;&#x2F;p&gt;
&lt;p&gt;The example also depicts a third example, &#x27;invert byte virtual device&#x27;, that
works similarily to &#x27;xor virtual device&#x27;, but instead of XORing each byte, it
inverts it.&lt;&#x2F;p&gt;
&lt;p&gt;All of these devices can be stacked one on another. In our example we can read
data from &#x27;invert byte virtual device&#x27;. This will put in motion several other
devices as well:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&#x27;invert byte device&#x27; will ask &#x27;xor device&#x27; for data,&lt;&#x2F;li&gt;
&lt;li&gt;&#x27;xor device&#x27; will ask &#x27;zero-byte device&#x27; for data,&lt;&#x2F;li&gt;
&lt;li&gt;&#x27;zero-byte device&#x27; will generate a NULL byte, and will return it to the
caller,&lt;&#x2F;li&gt;
&lt;li&gt;&#x27;xor device&#x27; will acquire this NULL byte, and it will perform an XOR &lt;code&gt;0xA1&lt;&#x2F;code&gt;
operation on it. Then, it will return the XORed data to the &#x27;invert byte device&#x27;.&lt;&#x2F;li&gt;
&lt;li&gt;&#x27;invert byte device&#x27; will get the XORed data, and will invert each byte of it.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The result of this operation will probably be next to useless, but it
demonstrates the stacking capability of &lt;code&gt;device-mapper&lt;&#x2F;code&gt;. If we switch the
zero-byte generator to a normal file, we suddenly have a poor-man encryption
system, based on XOR and NEG! ;)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cryptsetup&quot;&gt;Cryptsetup&lt;&#x2F;h2&gt;
&lt;p&gt;Our system of choice is LUKS, without any particular reason other than because
it supports a wide range of secure encryption algorithms. Before using it,
please be aware that one thing that LUKS doesn&#x27;t implement is support for
plausible deniability -- LUKS actually inserts its header into the encrypted
file, so everyone can see that this is an encrypted container.&lt;&#x2F;p&gt;
&lt;p&gt;This shouldn&#x27;t be a problem in sensitive scenarios, because we can always add
another &lt;code&gt;device-mapper&lt;&#x2F;code&gt; device that will encrypt the LUKS encrypted data, along
with its header. That&#x27;s why the device stacking feature is so useful.&lt;&#x2F;p&gt;
&lt;p&gt;We won&#x27;t use LUKS directly, because it&#x27;s designed to be used by the &lt;code&gt;cryptsetup&lt;&#x2F;code&gt;
frontend. To properly use LUKS, we have to specify the container (or the &quot;input
data&quot;). The device will store its encrypted data inside this container. We can
choose to have a simple file as the container, a disk drive, or another device.
Let&#x27;s choose a simple file, &lt;code&gt;container.bin&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s create a 100MB file that will be the container:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# dd if=&#x2F;dev&#x2F;zero of=container.bin bs=1M count=100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then, let&#x27;s create the LUKS structure inside it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# cryptsetup luksFormat container.bin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;WARNING!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;========&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;This will overwrite data on container.bin irrevocably.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Are you sure? (Type uppercase yes): YES&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enter passphrase:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Verify passphrase:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# file container.bin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;container.bin: LUKS encrypted file, ver 1 [aes, xts-plain64, sha1] UUID: 02dc91ee-e1d8-4918-bcd4-7536f91811a8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It used &lt;code&gt;xts-plain64&lt;&#x2F;code&gt; as a default encryption algorithm. You can tune up this
behavior by command-line settings.&lt;&#x2F;p&gt;
&lt;p&gt;Now we can create a &lt;code&gt;device-mapper&lt;&#x2F;code&gt; device by using &lt;code&gt;luksOpen&lt;&#x2F;code&gt; command:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# cryptsetup luksOpen container.bin container&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enter passphrase for container.bin:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# ls -la &#x2F;dev&#x2F;mapper&#x2F;container&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 7 09.11.2014 16:36 &#x2F;dev&#x2F;mapper&#x2F;container -&amp;gt; ..&#x2F;dm-2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As you can see, we have our first virtual device, &lt;code&gt;&#x2F;dev&#x2F;mapper&#x2F;container&lt;&#x2F;code&gt;. When
we read from this device, LUKS will decrypt the data from &lt;code&gt;container.bin&lt;&#x2F;code&gt; by
using the &lt;code&gt;xts-plain64&lt;&#x2F;code&gt; algorithm, and will feed our request with decrypted
data. When we&#x27;ll write into this device, LUKS will encrypt this data and store
it inside &lt;code&gt;container.bin&lt;&#x2F;code&gt; in encrypted form.&lt;&#x2F;p&gt;
&lt;p&gt;Now we can operate on this device as on any other device. We can create a
filesystem on it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mkfs.ext4 &#x2F;dev&#x2F;mapper&#x2F;container&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mke2fs 1.42.12 (29-Aug-2014)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Creating filesystem with 100352 1k blocks and 25168 inodes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filesystem UUID: ceb14da6-714a-4a53-9739-428bbffa336e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Superblock backups stored on blocks:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    8193, 24577, 40961, 57345, 73729&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Allocating group tables: done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Writing inode tables: done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Creating journal (4096 blocks): done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Writing superblocks and filesystem accounting information: done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mkdir &#x2F;tmp&#x2F;x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mount &#x2F;dev&#x2F;mapper&#x2F;container &#x2F;tmp&#x2F;x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# ls -la &#x2F;tmp&#x2F;x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;total 13&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr-xr-x  3 root root  1024 09.11.2014 16:39 .&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxrwxrwt 20 root root   560 09.11.2014 16:39 ..&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwx------  2 root root 12288 09.11.2014 16:39 lost+found&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We have created our first encrypted container! We can close it gracefully by
unmounting the filesystem and performing a &lt;code&gt;luksClose&lt;&#x2F;code&gt; command:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# umount &#x2F;tmp&#x2F;x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# cryptsetup luksClose container&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;limitations&quot;&gt;Limitations&lt;&#x2F;h2&gt;
&lt;p&gt;This approach has its limitations. We have created a 100MB container file, and
then we have created a filesystem on it. Our free space available for use is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# df -h &#x2F;tmp&#x2F;x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filesystem             Size  Used Avail Use% Mounted on&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;dev&#x2F;mapper&#x2F;container   91M  1.6M   83M   2% &#x2F;tmp&#x2F;x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It&#x27;s 83MB. What if, in the future, we would like to increase the size of this
container?&lt;&#x2F;p&gt;
&lt;p&gt;One option is to simply increase the size of the &lt;code&gt;container.bin&lt;&#x2F;code&gt; container file
(after removing all mappings first and performing &lt;code&gt;luksClose&lt;&#x2F;code&gt;). Then, after
mounting the filesystem, invoking a filesystem resize operation (for example by
using &lt;code&gt;resize2fs&lt;&#x2F;code&gt; if you&#x27;re using &lt;code&gt;ext4&lt;&#x2F;code&gt; filesystem, or &lt;code&gt;xfs_growfs&lt;&#x2F;code&gt; if you&#x27;re
on &lt;code&gt;xfs&lt;&#x2F;code&gt;) should be enough.&lt;&#x2F;p&gt;
&lt;p&gt;But there are scenarios that this won&#x27;t suffice. One such example is when using
a Dedicated Host bought in some server room, or a VPS, where you can just add
another storage nodes instead of resizing them. You can&#x27;t make the file larger
than the partition used to hold the file.&lt;&#x2F;p&gt;
&lt;p&gt;You can get around this limitation by entering one abstraction above physical
limitations. Enter Logical Volume Management!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;lvm2-logical-volume-management&quot;&gt;lvm2: Logical Volume Management&lt;&#x2F;h2&gt;
&lt;p&gt;The topic is as large as Pacific Ocean, so we will simply skip most of it,
focusing only on our use-case.&lt;&#x2F;p&gt;
&lt;p&gt;We can use &lt;code&gt;lvm&lt;&#x2F;code&gt; to create a new virtual drive (again, with &lt;code&gt;device-mapper&lt;&#x2F;code&gt;)
that will use our containers as physical file storage. This way, by having
multiple container files, each with its own file size, we can create a device
that will be as large as the sum of each container&#x27;s length. &lt;code&gt;lvm&lt;&#x2F;code&gt; driver will
figure out the best way to dispatch read and write reqests to proper file
containers, just like RAID controllers do. One big difference between LVM and
RAID is that LVM is more dynamic, and allows you to create, modify, resize and
deactivate logical volumes when the system is on-line and working. It actually
also supports performing filesystem snapshots, but this is one feature we won&#x27;t
actually use.&lt;&#x2F;p&gt;
&lt;p&gt;So, the layout of our system will look something like this:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;usage-of-encrypted-file-containers.html&#x2F;lvm.png&quot; alt=&quot;Flowchart 2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &#x27;Main Logical Volume&#x27; will be our virtual drive, which will contain a
filesystem. By using this layout, we will be able to increase the size of it
simply by adding more container files. Every container will be encrypted by
LUKS, so nothing will be stored as plaintext.&lt;&#x2F;p&gt;
&lt;p&gt;The nodes marked as &#x27;PV&#x27; are &lt;code&gt;physical volumes&lt;&#x2F;code&gt;, which are described in the next
subsection.&lt;&#x2F;p&gt;
&lt;p&gt;To properly create the LVM layout, we need four things:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A &#x27;logical volume&#x27;, which will be a mountable device,&lt;&#x2F;li&gt;
&lt;li&gt;A &#x27;volume group&#x27;, which will group our logical volumes (we will have only one
logical volume, but a group still is needed),&lt;&#x2F;li&gt;
&lt;li&gt;A &#x27;physical volume&#x27;, which will specify where exactly is the place for the
data to be written,&lt;&#x2F;li&gt;
&lt;li&gt;An encrypted space for the physical volume -- this was covered in previous
sections of this post.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Let&#x27;s create everything that is needed, going from the end of this list.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;luks-containers&quot;&gt;LUKS containers&lt;&#x2F;h3&gt;
&lt;p&gt;We will create three containers: &lt;code&gt;container1.bin&lt;&#x2F;code&gt;, &lt;code&gt;container2.bin&lt;&#x2F;code&gt; and
&lt;code&gt;container3.bin&lt;&#x2F;code&gt;. Each container will have a capacity of 100MB.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ for i in `seq 1 3`; do dd if=&#x2F;dev&#x2F;zero of=container$i.bin bs=1M count=100; done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;100+0 records in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;100+0 records out&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;104857600 bytes (105 MB) copied, 0.0443074 s, 2.4 GB&#x2F;s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;100+0 records in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;100+0 records out&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;104857600 bytes (105 MB) copied, 0.0390611 s, 2.7 GB&#x2F;s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;100+0 records in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;100+0 records out&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;104857600 bytes (105 MB) copied, 0.0388189 s, 2.7 GB&#x2F;s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ ls -la&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;total 307212&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr-xr-x 2 antek users      4096 Nov 11 12:05 .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr-xr-x 8 antek users      4096 Nov 11 12:05 ..&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rw-r--r-- 1 antek users 104857600 Nov 11 12:05 container1.bin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rw-r--r-- 1 antek users 104857600 Nov 11 12:05 container2.bin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-rw-r--r-- 1 antek users 104857600 Nov 11 12:05 container3.bin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then, we create three LUKS devices from each container, each with some password
(you can choose different password for each container, or one password for
everything -- depends on your paranoia level).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ for i in `seq 1 3`; do cryptsetup luksFormat container$i.bin; done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;WARNING!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;========&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;This will overwrite data on container1.bin irrevocably.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Are you sure? (Type uppercase yes): YES&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enter passphrase:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Verify passphrase:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;WARNING!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;========&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;This will overwrite data on container2.bin irrevocably.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Are you sure? (Type uppercase yes): YES&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enter passphrase:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Verify passphrase:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;WARNING!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;========&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;This will overwrite data on container3.bin irrevocably.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Are you sure? (Type uppercase yes): YES&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enter passphrase:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Verify passphrase:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ file container*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;container1.bin: LUKS encrypted file, ver 1 [aes, xts-plain64, sha1] UUID: 282f487a-b708-42ab-b403-667af624f667&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;container2.bin: LUKS encrypted file, ver 1 [aes, xts-plain64, sha1] UUID: 2d95d5bd-8528-4fdf-8954-57b3268c20c9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;container3.bin: LUKS encrypted file, ver 1 [aes, xts-plain64, sha1] UUID: ffa92cc0-c5e9-45dd-95d0-f33469e09dd1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then we open all containers to create proper &lt;code&gt;device-mapper&lt;&#x2F;code&gt; devices:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ sudo su&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# for i in `seq 1 3`; do cryptsetup luksOpen container$i.bin container$i; done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enter passphrase for container1.bin:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enter passphrase for container2.bin:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enter passphrase for container3.bin:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# ls -la &#x2F;dev&#x2F;mapper&#x2F;container*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 7 11.11.2014 12:10 &#x2F;dev&#x2F;mapper&#x2F;container1 -&amp;gt; ..&#x2F;dm-0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 7 11.11.2014 12:10 &#x2F;dev&#x2F;mapper&#x2F;container2 -&amp;gt; ..&#x2F;dm-1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 7 11.11.2014 12:10 &#x2F;dev&#x2F;mapper&#x2F;container3 -&amp;gt; ..&#x2F;dm-2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As you can see, we have created three encrypted devices in
&lt;code&gt;&#x2F;dev&#x2F;mapper&#x2F;container*&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;physical-volumes-pv&quot;&gt;Physical Volumes (PV)&lt;&#x2F;h3&gt;
&lt;p&gt;Now it&#x27;s time to create a LVM on the top of it. We
will use each &lt;code&gt;&#x2F;dev&#x2F;mapper&#x2F;container*&lt;&#x2F;code&gt; device as a LVM Physical Volume (&lt;code&gt;PV&lt;&#x2F;code&gt;).
Let&#x27;s create those PV&#x27;s:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# pvcreate &#x2F;dev&#x2F;mapper&#x2F;container{1,2,3}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Physical volume &amp;quot;&#x2F;dev&#x2F;mapper&#x2F;container1&amp;quot; successfully created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Physical volume &amp;quot;&#x2F;dev&#x2F;mapper&#x2F;container2&amp;quot; successfully created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Physical volume &amp;quot;&#x2F;dev&#x2F;mapper&#x2F;container3&amp;quot; successfully created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can verify that LVM registered those PVs properly:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# pvscan&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PV &#x2F;dev&#x2F;mapper&#x2F;container2         lvm2 [98.00 MiB]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PV &#x2F;dev&#x2F;mapper&#x2F;container1         lvm2 [98.00 MiB]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PV &#x2F;dev&#x2F;mapper&#x2F;container3         lvm2 [98.00 MiB]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Total: 3 [294.00 MiB] &#x2F; in use: 0 [0   ] &#x2F; in no VG: 3 [294.00 MiB]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We have about 300MB in all three physical volumes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;volume-group-vg&quot;&gt;Volume Group (VG)&lt;&#x2F;h3&gt;
&lt;p&gt;We can now create a Volume Group (&lt;code&gt;VG&lt;&#x2F;code&gt;). Volume group is a pool of physical
volumes (PVs). We group PVs together in a VG, to be able to create a virtual
Logical Volume (LV), that will be contained inside the VG.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# vgcreate example_vg &#x2F;dev&#x2F;mapper&#x2F;container{1,2,3}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Volume group &amp;quot;example_vg&amp;quot; successfully created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s verify that everything is in order:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# vgscan&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Reading all physical volumes.  This may take a while...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Found volume group &amp;quot;example_vg&amp;quot; using metadata type lvm2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# vgdisplay example_vg&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--- Volume group ---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VG Name               example_vg&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;System ID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Format                lvm2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Metadata Areas        3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Metadata Sequence No  1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VG Access             read&#x2F;write&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VG Status             resizable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MAX LV                0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Cur LV                0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Open LV               0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Max PV                0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Cur PV                3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Act PV                3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VG Size               288.00 MiB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PE Size               4.00 MiB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Total PE              72&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Alloc PE &#x2F; Size       0 &#x2F; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Free  PE &#x2F; Size       72 &#x2F; 288.00 MiB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VG UUID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;G2YvoH-YwIn-VB8V-aC92-9XPC-Ykj0-2EYdCR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;logical-volumes-lv&quot;&gt;Logical Volumes (LV)&lt;&#x2F;h3&gt;
&lt;p&gt;As you can see, we have 288MB free space in our VG. This means that we can
create one LV with the size of 288MB. We can also create 288 LV&#x27;s, each of size
of 1MB, but that won&#x27;t be very practical. Let&#x27;s create one LV, using all of
available space:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# lvcreate example_vg -L 288MB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Logical volume &amp;quot;lvol0&amp;quot; created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we have a logical volume &lt;code&gt;lvol0&lt;&#x2F;code&gt;, existing inside a volume group named
&lt;code&gt;example_vg&lt;&#x2F;code&gt;, distributed across &lt;code&gt;container*.bin&lt;&#x2F;code&gt; files. Here is our device:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# ls -la &#x2F;dev&#x2F;mapper&#x2F;example_vg*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 7 11.11.2014 12:23 &#x2F;dev&#x2F;mapper&#x2F;example_vg-lvol0 -&amp;gt; ..&#x2F;dm-3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As previously, we can create a filesystem on it. Let&#x27;s try &lt;code&gt;xfs&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# mkfs.xfs &#x2F;dev&#x2F;mapper&#x2F;example_vg-lvol0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;meta-data=&#x2F;dev&#x2F;mapper&#x2F;example_vg-lvol0 isize=256    agcount=4, agsize=18432 blks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         =                       sectsz=512   attr=2, projid32bit=1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         =                       crc=0        finobt=0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;data     =                       bsize=4096   blocks=73728, imaxpct=25&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         =                       sunit=0      swidth=0 blks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;naming   =version 2              bsize=4096   ascii-ci=0 ftype=0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;log      =internal log           bsize=4096   blocks=853, version=2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         =                       sectsz=512   sunit=0 blks, lazy-count=1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;realtime =none                   extsz=4096   blocks=0, rtextents=0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can also mount it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# mkdir &#x2F;tmp&#x2F;x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# mount &#x2F;dev&#x2F;mapper&#x2F;example_vg-lvol0 &#x2F;tmp&#x2F;x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# df -h &#x2F;tmp&#x2F;x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filesystem                    Size  Used Avail Use% Mounted on&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;dev&#x2F;mapper&#x2F;example_vg-lvol0  285M   15M  271M   6% &#x2F;tmp&#x2F;x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we can put files in &lt;code&gt;&#x2F;tmp&#x2F;x&lt;&#x2F;code&gt;, we have 271MB free space!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;resizing&quot;&gt;Resizing&lt;&#x2F;h3&gt;
&lt;p&gt;Let&#x27;s try resizing our virtual filesystem by additional 100MB. Here&#x27;s what we need to do:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Unmount it,&lt;&#x2F;li&gt;
&lt;li&gt;Add a new PV to our VG,&lt;&#x2F;li&gt;
&lt;li&gt;Resize our LV, increasing its size,&lt;&#x2F;li&gt;
&lt;li&gt;Resize the filesystem on the LV.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Unmounting is easy:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# unmount &#x2F;tmp&#x2F;x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now let&#x27;s create a new container file, and initialize a LUKS filter on it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# dd if=&#x2F;dev&#x2F;zero of=container4.bin bs=1M count=100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;100+0 records in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;100+0 records out&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;104857600 bytes (105 MB) copied, 0.0398605 s, 2.6 GB&#x2F;s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# cryptsetup luksFormat container4.bin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;WARNING!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;========&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;This will overwrite data on container4.bin irrevocably.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Are you sure? (Type uppercase yes): YES&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enter passphrase:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Verify passphrase:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# cryptsetup luksOpen container4.bin container4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enter passphrase for container4.bin:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then let&#x27;s create a PV in the new container:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# pvcreate &#x2F;dev&#x2F;mapper&#x2F;container4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Physical volume &amp;quot;&#x2F;dev&#x2F;mapper&#x2F;container4&amp;quot; successfully created&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then, let&#x27;s add this PV into the pool of VG&#x27;s physical volumes, so that our LV
can use it. We&#x27;re performing this by using the &lt;code&gt;vgextend&lt;&#x2F;code&gt; command:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# vgextend example_vg &#x2F;dev&#x2F;mapper&#x2F;container4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Volume group &amp;quot;example_vg&amp;quot; successfully extended&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# vgdisplay example_vg&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--- Volume group ---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VG Name               example_vg&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;System ID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Format                lvm2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Metadata Areas        4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Metadata Sequence No  3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VG Access             read&#x2F;write&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VG Status             resizable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MAX LV                0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Cur LV                1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Open LV               1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Max PV                0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Cur PV                4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Act PV                4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VG Size               384.00 MiB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PE Size               4.00 MiB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Total PE              96&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Alloc PE &#x2F; Size       72 &#x2F; 288.00 MiB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Free  PE &#x2F; Size       24 &#x2F; 96.00 MiB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VG UUID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;G2YvoH-YwIn-VB8V-aC92-9XPC-Ykj0-2EYdCR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As you can see in the output of &lt;code&gt;vgdisplay&lt;&#x2F;code&gt; command, our VG has a size of 384MB.
288MB of those are used by our LV. 96MB are free -- this is our fourth container
file, created and added just now.&lt;&#x2F;p&gt;
&lt;p&gt;Now we can resize the LV, since we acquired some free space inside our VG. The
&lt;code&gt;-l 100%VG&lt;&#x2F;code&gt; specifier describes the new size of the LV -- it means: &#x27;100% of
current VG&#x27;, so it simply changes the LV to fill up 100% of its VG. Note that
there is no space between the percent character &lt;code&gt;%&lt;&#x2F;code&gt; and &lt;code&gt;VG&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# lvextend &#x2F;dev&#x2F;example_vg&#x2F;lvol0 -l 100%VG&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Size of logical volume example_vg&#x2F;lvol0 changed from 288.00 MiB (72 extents) to 384.00 MiB (96 extents).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Logical volume lvol0 successfully resized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So far so good. Now it&#x27;s time to tell &lt;code&gt;xfs&lt;&#x2F;code&gt; filesystem to make use of new free
space.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# xfs_growfs &#x2F;dev&#x2F;mapper&#x2F;example_vg-lvol0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;meta-data=&#x2F;dev&#x2F;mapper&#x2F;example_vg-lvol0 isize=256    agcount=4, agsize=18432 blks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         =                       sectsz=512   attr=2, projid32bit=1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         =                       crc=0        finobt=0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;data     =                       bsize=4096   blocks=73728, imaxpct=25&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         =                       sunit=0      swidth=0 blks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;naming   =version 2              bsize=4096   ascii-ci=0 ftype=0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;log      =internal               bsize=4096   blocks=853, version=2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         =                       sectsz=512   sunit=0 blks, lazy-count=1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;realtime =none                   extsz=4096   blocks=0, rtextents=0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;data blocks changed from 73728 to 98304&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s try to mount the &lt;code&gt;xfs&lt;&#x2F;code&gt; volume now, and see its new size:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# mount &#x2F;dev&#x2F;mapper&#x2F;example_vg-lvol0 &#x2F;tmp&#x2F;x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[root@hydra blogpost]# df -h &#x2F;tmp&#x2F;x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filesystem                    Size  Used Avail Use% Mounted on&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;dev&#x2F;mapper&#x2F;example_vg-lvol0  381M   20M  362M   6% &#x2F;tmp&#x2F;x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We have now 362MB of free space. Our volume has been resized by adding another
file into the LVM pool. Our work is done ;).&lt;&#x2F;p&gt;
&lt;p&gt;Please note that &lt;code&gt;xfs&lt;&#x2F;code&gt; doesn&#x27;t support &lt;em&gt;shrinking&lt;&#x2F;em&gt; the filesystem. So growing it
is a one-way trip! There may be other filesystems that support shrinking
operation though.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rebooting-the-system&quot;&gt;Rebooting the system&lt;&#x2F;h2&gt;
&lt;p&gt;How to mount the volume after rebooting the system? On modern Linux
distributions LVM should pick up all PVs and VGs that are appearing in the
system automatically. So all you need to do is to open LUKS containers:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# cryptsetup luksOpen container{1,2,3,4}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After &lt;code&gt;luksOpen&lt;&#x2F;code&gt;&#x27;ing them all, you should have &lt;code&gt;&#x2F;dev&#x2F;mapper&#x2F;example_vg-lvol0&lt;&#x2F;code&gt;
already present on your system, ready to be mounted into the mountpoint you&#x27;ve
chosen.&lt;&#x2F;p&gt;
&lt;!--
vim:ft=markdown:et:
--&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Control over symbol exports in GCC</title>
        <published>2014-10-30T00:00:00+00:00</published>
        <updated>2014-10-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/control-over-symbol-exports-in-gcc.html/"/>
        <id>https://anadoxin.org/blog/control-over-symbol-exports-in-gcc.html/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/control-over-symbol-exports-in-gcc.html/">&lt;p&gt;When dealing with creation of shared objects, one should keep in mind that the
longer is the list of their exported symbols, the longer time is taken by the
dynamic linker during the loading process.&lt;&#x2F;p&gt;
&lt;p&gt;There is much information regarding the rules which should be followed when one
tries to create a shared object. There is a great paper written by the &lt;code&gt;glibc&lt;&#x2F;code&gt;
maintainer, Ulrich Drepper, which covers most of the topics. You can find the
paper on your favourite search engine (try searching for &quot;How to write shared
libraries by Ulrich Drepper&quot;).&lt;&#x2F;p&gt;
&lt;p&gt;One of the important points is the restriction of exported symbols in a shared
object. When creating an ELF shared object (by convention, a file named as
&lt;code&gt;lib*.so&lt;&#x2F;code&gt;), all symbols are marked as public, hence included in the object&#x27;s
export symbol table. Obviously, existence of every symbol in the export table is
not optimal. Export table should be populated only by the API of the shared
object, because nobody every will (nobody ever &lt;em&gt;should&lt;&#x2F;em&gt;) use any of the internal
structures, which the symbols are describing. Exported symbols are often
considered as an Application Binary Interface (&lt;code&gt;ABI&lt;&#x2F;code&gt;), which should be
compatible between different library versions. Maintaining the ABI of an
internal structure effectively removes the possibility of any practical
modification.&lt;&#x2F;p&gt;
&lt;p&gt;Normally, when you create a shared object on Linux, all of its symbols are
exported by default. Consider this example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;iostream&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;using namespace std;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; function1&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cout &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;hi&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; entry_point&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;	function1&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The example shows a shared object that contains an API function (that is a
function designed to be called from a different module, an entry point to the
shared library&#x27;s functionality). This &lt;code&gt;entry_point&lt;&#x2F;code&gt; API function uses a helper
function, &lt;code&gt;function1&lt;&#x2F;code&gt; to perform some task. Let&#x27;s compile this shared object:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ g++ code.cpp -o libcode.so -shared -fPIC&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and let&#x27;s glance at the export table:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ nm -CD libcode.so | grep &amp;quot; T &amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;00000000000007c8 T entry_point()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;00000000000007ac T function1()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000868 T _fini&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000668 T _init&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We have 4 symbols insite the &lt;code&gt;text&lt;&#x2F;code&gt; segment of &lt;code&gt;libcode.so&lt;&#x2F;code&gt;. &lt;code&gt;_fini&lt;&#x2F;code&gt; and &lt;code&gt;_init&lt;&#x2F;code&gt;
are automalically added export symbols that relate to initialization and
finalization of the object. Two other symbols are ours. Our goal is to make a
shared library that will put &lt;code&gt;entry_point&lt;&#x2F;code&gt; in the export table, and at the same
time leaving &lt;code&gt;function1&lt;&#x2F;code&gt; from this table.&lt;&#x2F;p&gt;
&lt;p&gt;There are two methods for doing this: by using the &lt;code&gt;-fvisibility&lt;&#x2F;code&gt; option, and
linker (&lt;code&gt;ld&lt;&#x2F;code&gt;) version script.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;using-fvisibility-compiler-option&quot;&gt;Using `fvisibility&#x27; compiler option&lt;&#x2F;h1&gt;
&lt;p&gt;The compiler flag &lt;code&gt;-fvisibility=hidden&lt;&#x2F;code&gt; is designed for dealing with exactly
this kind of problems. By using this option, the user tells the compiler to
exclude &lt;em&gt;all&lt;&#x2F;em&gt; of the symbols from the export table:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ g++ code.cpp -o libcode.so -shared -fPIC -fvisibility=hidden&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ nm -CD libcode.so | grep &amp;quot; T &amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;00000000000007e8 T _fini&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;00000000000005f8 T _init&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But, we want also to include the &lt;code&gt;entry_point&lt;&#x2F;code&gt; function in the table, because
it&#x27;s our API function. This is why we need to change the source code a little
bit:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;iostream&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;using namespace std;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; function1&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cout &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;hi&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;__attribute__&lt;&#x2F;span&gt;&lt;span&gt; ((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;visibility&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;default&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; entry_point&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;	function1&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After compilation, our goal is matched:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ g++ code.cpp -o libcode.so -shared -fPIC -fvisibility=hidden&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ nm -CD libcode.so | grep &amp;quot; T &amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000778 T entry_point()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000818 T _fini&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000628 T _init&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;__attribute__ ((visibility (&quot;default&quot;)))&lt;&#x2F;code&gt; is very similar to
&lt;code&gt;__declspec(dllexport)&lt;&#x2F;code&gt; that can be found on Microsoft&#x27;s compilers. In fact, GCC
should handle it as well. The attribute overrides the &lt;code&gt;-fvisibility=hidden&lt;&#x2F;code&gt;
compiler option only for only one symbol, and makes it public. That&#x27;s why it&#x27;s
included in the export table.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;static-library-used-by-a-shared-library-problems&quot;&gt;Static library used by a shared library problems&lt;&#x2F;h2&gt;
&lt;p&gt;However, there is one problem with this approach. If our shared library is large
enough, it may use other libraries that are statically linked. Let&#x27;s consider
another example.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s suppose we have a static library, &lt;code&gt;libutil.a&lt;&#x2F;code&gt;, that is statically linked
into our shared library, &lt;code&gt;libcode.so&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Here is our &lt;code&gt;util.cpp&lt;&#x2F;code&gt; file, that is the source of the static library:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;iostream&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;using namespace std;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; util_function&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cout &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;hello from util function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s compile it, and build a static library from this code:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ g++ util.cpp -o util.o -c -fPIC&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ ar r libutil.a util.o&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We have now &lt;code&gt;libutil.a&lt;&#x2F;code&gt; static library which can be used in our shared object.
Let&#x27;s modify the shared object to include a reference to the code of
&lt;code&gt;libutil.a&lt;&#x2F;code&gt; (without it, &lt;code&gt;libutil.a&lt;&#x2F;code&gt; would be dropped in the linking process):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;iostream&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;using namespace std;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;extern void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; util_function&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; function1&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;	util_function&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	cout &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;hi&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;__attribute__&lt;&#x2F;span&gt;&lt;span&gt; ((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;visibility&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;default&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; entry_point&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;	function1&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s compile our shared library and see its export table:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ g++ code.cpp libutil.a -o libcode.so -shared -fPIC -fvisibility=hidden&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ nm -CD libcode.so | grep &amp;quot; T &amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;00000000000007ed T entry_point()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000858 T util_function()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000918 T _fini&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000000000000688 T _init&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As you can see, &lt;code&gt;util_function&lt;&#x2F;code&gt; is included in the list, but we don&#x27;t want it
there. How to fix this?&lt;&#x2F;p&gt;
&lt;p&gt;One solution is to add &lt;code&gt;-fvisibility=hidden&lt;&#x2F;code&gt; to &lt;code&gt;libutil.a&lt;&#x2F;code&gt; library&#x27;s build
process, but sometimes we don&#x27;t have the control over it. What then?&lt;&#x2F;p&gt;
&lt;p&gt;Linker scripts to the rescue.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;using-ld-linker-version-script&quot;&gt;Using `ld&#x27; linker version script&lt;&#x2F;h1&gt;
&lt;p&gt;We need to get rid of the &lt;code&gt;util_function&lt;&#x2F;code&gt; symbol during the linking process,
because we may not have any control over the compilation of &lt;code&gt;libutil.a&lt;&#x2F;code&gt; library.&lt;&#x2F;p&gt;
&lt;p&gt;Fortunately, &lt;code&gt;ld&lt;&#x2F;code&gt; supports export table filtering (and much more) by using a
&quot;version script&quot;, which will contain some definitions on what to include, and
what to skip. It even supports wildcards which also may help.&lt;&#x2F;p&gt;
&lt;p&gt;So, let&#x27;s skip the &lt;code&gt;-fvisibility=hidden&lt;&#x2F;code&gt; option for now, and build our shared
library like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ g++ code.cpp libutil.a -o libcode.so -shared -fPIC&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then, create a text file, &lt;code&gt;libcode.version&lt;&#x2F;code&gt;, with this content:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;CODEABI_1.0 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	global: *entry_point*;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	local: *;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This version file tells the linker, that all symbols (&lt;code&gt;*&lt;&#x2F;code&gt;) should be considered
as &lt;em&gt;local&lt;&#x2F;em&gt; symbols (that is: hidden), and all symbols that match the wildcard
&lt;code&gt;*entry_point*&lt;&#x2F;code&gt; should be considered as &lt;em&gt;global&lt;&#x2F;em&gt; (so, visible).&lt;&#x2F;p&gt;
&lt;p&gt;Compilation is done by the &lt;code&gt;g++&lt;&#x2F;code&gt; driver:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ g++ code.cpp libutil.a -o shared -fPIC -Wl,--version-script=libcode.version&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Verification:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ nm -CD libcode.so | grep &amp;quot; T &amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;000000000000074d T entry_point()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It even stripped out the &lt;code&gt;_init&lt;&#x2F;code&gt; and &lt;code&gt;_fini&lt;&#x2F;code&gt; symbols. Job done!&lt;&#x2F;p&gt;
&lt;p&gt;The problem with this approach is that it can&#x27;t handle some more complicated
scenarios, like filtering only some symbols that are using C++ templates. Some
of the template-based symbols in C++ can easily grow up to few hundred
characters, but you probably know what I mean. Once you start using functions
from &lt;code&gt;std::&lt;&#x2F;code&gt;, you&#x27;ll &lt;em&gt;know&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Please do some reading about the linker&#x27;s version scripts, because it allows you
to perform some really cool things, like symbol versioning!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Sending ATA commands on Linux</title>
        <published>2014-09-12T00:00:00+00:00</published>
        <updated>2014-09-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/sending-ata-commands-on-linux.html/"/>
        <id>https://anadoxin.org/blog/sending-ata-commands-on-linux.html/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/sending-ata-commands-on-linux.html/">&lt;p&gt;It appears that any user can send an ATA message on Linux. The function that
allows this is called &lt;code&gt;ioctl&lt;&#x2F;code&gt;, by using message identifier &lt;code&gt;0x31F&lt;&#x2F;code&gt;
(&lt;code&gt;HDIO_DRIVE_CMD&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;It is possible to send, i.e. &lt;code&gt;ATA IDENTIFY&lt;&#x2F;code&gt; message by using &lt;code&gt;0xEC&lt;&#x2F;code&gt; message.
This command should return a device identification information. Other status
indication message is implemented by the &lt;code&gt;0xA1&lt;&#x2F;code&gt; message, but the device needs to
properly implement PACKET extensions, so it needs to be an ATAPI device.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;iostream&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;fcntl.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;unistd.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;errno.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;string.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;stdlib.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;stdio.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;stdint.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;sys&#x2F;ioctl.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;using namespace std;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;	int&lt;&#x2F;span&gt;&lt;span&gt; fd &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; ::open&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;&#x2F;dev&#x2F;sda&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, O_RDONLY &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; O_DIRECT);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span&gt;(fd &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;!= -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;		uint8_t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; buf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;512&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;EC&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;		int&lt;&#x2F;span&gt;&lt;span&gt; ret &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; ::ioctl&lt;&#x2F;span&gt;&lt;span&gt;(fd,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;31F&lt;&#x2F;span&gt;&lt;span&gt;, buf);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;		for&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 512&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span&gt;i) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;			::putchar&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;buf&lt;&#x2F;span&gt;&lt;span&gt;[i]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;		::perror&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;open&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;	::close&lt;&#x2F;span&gt;&lt;span&gt;(fd);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The data you&#x27;ll get will be encoded in big endian notation, so you need to fix
this by using necessary shifts and bswaps.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;sending-ata-commands-on-linux.html&#x2F;ata-identify.png&quot; alt=&quot;ATA Identify example&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;!-- vim:set ft=markdown: --&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fixing ugly Java fonts</title>
        <published>2014-09-08T00:00:00+00:00</published>
        <updated>2014-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/fixing-ugly-java-fonts.html/"/>
        <id>https://anadoxin.org/blog/fixing-ugly-java-fonts.html/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/fixing-ugly-java-fonts.html/">&lt;p&gt;Today I got an e-mail from Jetbrains about the release of their new Integrated Development
Environment called CLion (&quot;SeaLion&quot;). Being a curious creature I decided to
check it out by using the Early Access Program which is open to public. After
running the IDE, my biggest problem was the font rendering, which can be seen on
this screenshot (click to see the full size):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;fixing-ugly-java-fonts.html&#x2F;clion_hint_off.png&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;fixing-ugly-java-fonts.html&#x2F;clion_hint_off.png&quot; alt=&quot;Hinting off&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Swing and Java are nice in theory, but in practice they&#x27;re often not so nice. CLion is
not an exception. Fortunately, some shortcomings can be fixed pretty easily.&lt;&#x2F;p&gt;
&lt;p&gt;To fix the font issue, just force Java&#x27;s &lt;code&gt;awt.useSystemAAFontSettings&lt;&#x2F;code&gt; setting
to &lt;code&gt;on&lt;&#x2F;code&gt;. You can do this in many different ways, but I decided to use
&lt;code&gt;$_JAVA_OPTIONS&lt;&#x2F;code&gt; variable in my shell&#x27;s startup script, &lt;code&gt;.zshrc&lt;&#x2F;code&gt;. For &lt;code&gt;bash&lt;&#x2F;code&gt;,
the method is almost identical, you just have to put your settings inside
&lt;code&gt;.bashrc&lt;&#x2F;code&gt; (but you already knew that).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;export&lt;&#x2F;span&gt;&lt;span&gt; _JAVA_OPTIONS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;-Dawt.useSystemAAFontSettings=on&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After this modification, CLion started to look more friendly:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;fixing-ugly-java-fonts.html&#x2F;clion_hint_on.png&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;fixing-ugly-java-fonts.html&#x2F;clion_hint_on.png&quot; alt=&quot;Hinting on&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Still not as good as in my Vim in the terminal window, but close enough!&lt;&#x2F;p&gt;
&lt;p&gt;The IDE itself is also quite nice. Slow speed can be irritating, but it&#x27;s
bearable, provided the product is good.&lt;&#x2F;p&gt;
&lt;!-- vim:set ft=markdown: --&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Enabling core dumps on Linux</title>
        <published>2014-08-16T00:00:00+00:00</published>
        <updated>2014-08-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/enabling-core-dumps-on-linux.html/"/>
        <id>https://anadoxin.org/blog/enabling-core-dumps-on-linux.html/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/enabling-core-dumps-on-linux.html/">&lt;p&gt;When creating a Linux application in a native language, such as C or
C++, it&#x27;s obvious that eventually a bug will appear. Some are easy to
fix, but sometimes they&#x27;re not. Normally you could just run &lt;code&gt;gdb&lt;&#x2F;code&gt; to
figure out how to fix it, but what about a situation when the program
runs smoothly under &lt;code&gt;gdb&lt;&#x2F;code&gt;, but crashes when running without any
debugger?&lt;&#x2F;p&gt;
&lt;p&gt;There is one feature that can be used to troubleshoot the problem, and
its name is: &lt;em&gt;core dumps&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A core dump is a special file that is created when the process
crashes. It&#x27;s stored in binary format, but with tools like &lt;code&gt;gdb&lt;&#x2F;code&gt; it&#x27;s
not hard to analyze it. In fact, you don&#x27;t need to analyze it at all
-- it simply stores the current crashed environment of the process in
such a way, that &lt;code&gt;gdb&lt;&#x2F;code&gt; can be used normally, like in every other
debugging session. The only difference is that you won&#x27;t be able to
execute anything from such crashed process.&lt;&#x2F;p&gt;
&lt;p&gt;You can enable core dump file generation by using the &lt;code&gt;ulimit&lt;&#x2F;code&gt; command:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ ulimit -c unlimited&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will enable core dump generation for crashed applications invoked
from &lt;em&gt;the current shell&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ .&#x2F;crash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Segmentation fault&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ ls core*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;core.2123&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;2123&lt;&#x2F;code&gt; is the &lt;em&gt;process id&lt;&#x2F;em&gt; of the crashed application. You can load
this core dump to &lt;code&gt;gdb&lt;&#x2F;code&gt; by providing its name in the argument list for
&lt;code&gt;gdb&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ gdb crash core.2123&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;Gdb&lt;&#x2F;code&gt; will notify about loading the file with messages like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ gdb crash core.2123&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;....&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Core was generated by `.&#x2F;crash&amp;#39;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;....&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can use standard &lt;code&gt;bt&lt;&#x2F;code&gt; command to build the offending stacktrace:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(gdb) bt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#0  0x00007f8955ba4d67 in raise () from &#x2F;usr&#x2F;lib&#x2F;libc.so.6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#1  0x00007f8955ba6118 in abort () from &#x2F;usr&#x2F;lib&#x2F;libc.so.6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#2  0x00007f8955be4f93 in __libc_message () from &#x2F;usr&#x2F;lib&#x2F;libc.so.6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#3  0x00007f8955bea88e in malloc_printerr () from &#x2F;usr&#x2F;lib&#x2F;libc.so.6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#4  0x00007f8955beb04b in _int_free () from &#x2F;usr&#x2F;lib&#x2F;libc.so.6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#5  0x00007f89564fdacc in std::string::assign(std::string const&amp;amp;) () from &#x2F;usr&#x2F;lib&#x2F;libstdc++.so.6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#6  0x000000000044b551 in DataVisualizer::setCaptionText (this=0x1b831f0, s=&amp;quot;ls&amp;quot;) at &#x2F;home&#x2F;antek&#x2F;workspace&#x2F;mdhexedit&#x2F;lib&#x2F;plugins&#x2F;interfaces&#x2F;DataVisualizer.h:24&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#7  0x0000000000448eda in MainInstance::getFileContextForNewFile (this=0x1aea058, captionText=&amp;quot;ls&amp;quot;) at ..&#x2F;src&#x2F;ui&#x2F;MainInstance.cpp:138&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#8  0x0000000000432bb6 in FileMenu::loadFile (this=0x1af4e00, fileName=&amp;quot;&#x2F;bin&#x2F;ls&amp;quot;) at ..&#x2F;src&#x2F;ui&#x2F;menus&#x2F;FileMenu.cpp:78&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Way better than printf-debugging, don&#x27;t you think?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;i-did-everything-from-above-and-i-m-still-not-getting-any-coredumps&quot;&gt;I did everything from above, and I&#x27;m still not getting any coredumps!&lt;&#x2F;h2&gt;
&lt;p&gt;Are you using &lt;code&gt;systemd&lt;&#x2F;code&gt;? It probably depends on the distribution, but sometimes
&lt;code&gt;systemd&lt;&#x2F;code&gt; eats all the coredumps and stores them inside its own journal.&lt;&#x2F;p&gt;
&lt;p&gt;You can test if this is the case for your system by issuing a simple command:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ coredumpctl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For example, on my home system, the output of &lt;code&gt;coredumpctl&lt;&#x2F;code&gt; looks something like
this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pon 2014-06-30 20:21:59 CEST   6705  1000   100  11 &#x2F;personal&#x2F;antek&#x2F;.local&#x2F;share&#x2F;Steam&#x2F;SteamApps&#x2F;common&#x2F;dota 2 beta&#x2F;dota_linux&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wto 2014-07-01 15:49:17 CEST   1660     0     0   6 &#x2F;usr&#x2F;bin&#x2F;python3.4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wto 2014-07-01 21:50:30 CEST  18408  1000   100   6 &#x2F;home&#x2F;antek&#x2F;.local&#x2F;share&#x2F;Steam&#x2F;SteamApps&#x2F;common&#x2F;Sid Meier&amp;#39;s Civilization V&#x2F;Civ5XP&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;śro 2014-07-02 15:38:49 CEST   1422     0     0   6 &#x2F;usr&#x2F;bin&#x2F;python3.4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;czw 2014-07-03 10:05:46 CEST   1410     0     0   6 &#x2F;usr&#x2F;bin&#x2F;python3.4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;czw 2014-07-03 12:06:45 CEST   2515  1000   100  11 &#x2F;home&#x2F;antek&#x2F;dev&#x2F;mtf&#x2F;mtf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;czw 2014-07-03 12:07:15 CEST   2538  1000   100  11 &#x2F;home&#x2F;antek&#x2F;dev&#x2F;mtf&#x2F;mtf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can extract the coredump you&#x27;re interested in by using &lt;code&gt;coredumpctl&lt;&#x2F;code&gt;. For
example, to extract the crash from 2014-07-03 12:07:15, you can simply invoke:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ coredumpctl dump 2538 -o core.out&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will dump this coredump directly into the &lt;code&gt;core.out&lt;&#x2F;code&gt; file. But, consider
using the &lt;code&gt;coredumpctl gdb&lt;&#x2F;code&gt; command as well.&lt;&#x2F;p&gt;
&lt;!-- vim:set ft=markdown: --&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>New GCC on an old Linux distribution</title>
        <published>2014-08-05T00:00:00+00:00</published>
        <updated>2014-08-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/new-gcc-on-an-old-linux-distribution.html/"/>
        <id>https://anadoxin.org/blog/new-gcc-on-an-old-linux-distribution.html/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/new-gcc-on-an-old-linux-distribution.html/">&lt;p&gt;Sometimes you need to have a new version of &lt;code&gt;gcc&lt;&#x2F;code&gt; (i.e. to be able to leverage
the features from &lt;code&gt;C++11&lt;&#x2F;code&gt; standard), but you have an old distribution which
doesn&#x27;t have new &lt;code&gt;gcc&lt;&#x2F;code&gt; inside its repository. Here&#x27;s how you can compile your
own &lt;code&gt;gcc&lt;&#x2F;code&gt; on that distribution.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;acquire-gcc-tarball&quot;&gt;Acquire gcc tarball&lt;&#x2F;h2&gt;
&lt;p&gt;First you need to download the main &lt;code&gt;gcc&lt;&#x2F;code&gt; tarball from the official &lt;code&gt;gcc&lt;&#x2F;code&gt;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gcc.gnu.org&#x2F;mirrors.html&quot;&gt;website&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ wget ftp:&#x2F;&#x2F;gd.tuwien.ac.at&#x2F;gnu&#x2F;gcc&#x2F;releases&#x2F;gcc-4.9.0&#x2F;gcc-4.9.0.tar.bz2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After downloading, unpack the archive to some directory. Make sure you&#x27;ll have
enough space to compile the whole package though. I don&#x27;t remember exactly how
much space it will take, but it&#x27;s safe to assume that it will take &lt;em&gt;a lot&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;re installing it on a virtual machine (I did), maybe it&#x27;s a good idea to
use some kind of networked file system solution, like &lt;code&gt;NFS&lt;&#x2F;code&gt;, or at last &lt;code&gt;Samba&lt;&#x2F;code&gt;
(&lt;code&gt;sshfs&lt;&#x2F;code&gt; should also work). This way you would host all of the temporary object
files on you host machine, which probably has lots of gigabytes of free space,
ready to be used (right?).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ tar xfj gcc-*.tar.bz2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will unpack the package to the current directory. For the purposes of this
post, I&#x27;ll assume this directory will be named &lt;code&gt;&#x2F;srv&#x2F;vm&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;acquire-prerequisites&quot;&gt;Acquire prerequisites&lt;&#x2F;h2&gt;
&lt;p&gt;Next, you&#x27;ll need some thirdparty libraries required by &lt;code&gt;gcc&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;1-gmp&quot;&gt;1. GMP&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;GMP&lt;&#x2F;code&gt; (GNU Multiple Precision Library) - &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gmplib.org&#x2F;&quot;&gt;website&lt;&#x2F;a&gt;. Unpack it with:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ tar xfj gmp-*.tar.bz2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then create symbolic link of newly created directory to the &lt;code&gt;gmp&lt;&#x2F;code&gt; directory,
like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ ln -sf gmp-6.0.0 gmp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It should result in having the directory placed in &lt;code&gt;&#x2F;srv&#x2F;vm&#x2F;gcc-4.9.0&#x2F;gmp&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This way the build system of &lt;code&gt;gcc&lt;&#x2F;code&gt; should handle building this library together with &lt;code&gt;gcc&lt;&#x2F;code&gt; itself.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;2-mpfr&quot;&gt;2. MPFR&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;MPFR&lt;&#x2F;code&gt; (Multiple-Precision Floating-point computations with correct Rounding) -
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.mpfr.org&#x2F;&quot;&gt;website&lt;&#x2F;a&gt;. Unpack it, and create a symbolic link of its
directory to the &lt;code&gt;mpfr&lt;&#x2F;code&gt; directory.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;3-mpc&quot;&gt;3. MPC&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;MPC&lt;&#x2F;code&gt; (expansion over &lt;code&gt;MPFR&lt;&#x2F;code&gt; if I understand it correctly) -
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.multiprecision.org&#x2F;&quot;&gt;website&lt;&#x2F;a&gt;. Unpack it, and create a symbolic
link of its directory to the &lt;code&gt;mpc&lt;&#x2F;code&gt; directory.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;4-isl&quot;&gt;4. ISL&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;ISL&lt;&#x2F;code&gt; (Integer Set Library) - &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;isl.gforge.inria.fr&#x2F;&quot;&gt;website&lt;&#x2F;a&gt;. Unpack
it, and create a symbolic link of its directory to the &lt;code&gt;isl&lt;&#x2F;code&gt; directory.&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;re getting some compilation errors related to &lt;code&gt;isl_int&lt;&#x2F;code&gt;, use an older
version of the library, before &lt;code&gt;0.13&lt;&#x2F;code&gt;. The &lt;code&gt;0.13&lt;&#x2F;code&gt; version removes the
&lt;code&gt;isl_int&lt;&#x2F;code&gt; symbol, so this major update could be &lt;em&gt;too major&lt;&#x2F;em&gt; for other
libraries (like CLooG). The version that worked for me is &lt;code&gt;0.12.2&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If you do need to change the version of the &lt;code&gt;ISL&lt;&#x2F;code&gt; library, make sure you&#x27;ll
clean the current configuration cache, created after running &lt;code&gt;configure&lt;&#x2F;code&gt;
script. Best way is to remove the whole source directory and recreate it from
scratch. Oh, maybe &lt;code&gt;make distclean&lt;&#x2F;code&gt; will help too.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;5-cloog&quot;&gt;5. CLooG&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;code&gt;CLooG&lt;&#x2F;code&gt; (Chunky LOOp Generator) - &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;cloog.org&quot;&gt;website&lt;&#x2F;a&gt;. Unpack it, and
create a symbolic link of its directory to the &lt;code&gt;cloog&lt;&#x2F;code&gt; directory.&lt;&#x2F;p&gt;
&lt;p&gt;Of course, you will also need standard combo in the form of &lt;code&gt;autotools&lt;&#x2F;code&gt;, older
version of the compiler, but that&#x27;s pretty obvious, so I&#x27;ll just skip it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;compilation&quot;&gt;Compilation&lt;&#x2F;h2&gt;
&lt;p&gt;After installing the dependencies, next step is pretty straightforward:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ .&#x2F;configure --disable-multilib --prefix=&#x2F;usr&#x2F;local&#x2F;gcc49 --enable-threads --enable-languages=c,c++&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ make&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It is probably OK to get some errors, as long they&#x27;re not stopping the build
process. Please note that this process &lt;em&gt;will&lt;&#x2F;em&gt; take a long time, so you&#x27;ll have
to plan it ahead.&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;re trying to compile it through an &lt;code&gt;ssh&lt;&#x2F;code&gt; connection, I suggest you use
a terminal detaching tool like &lt;code&gt;screen&lt;&#x2F;code&gt; or &lt;code&gt;tmux&lt;&#x2F;code&gt;, so you&#x27;ll be able to close
the connection without interrupting the build.&lt;&#x2F;p&gt;
&lt;p&gt;To finish the process, don&#x27;t forget to &lt;code&gt;make install&lt;&#x2F;code&gt;. Your new gcc will be
installed to &lt;code&gt;&#x2F;usr&#x2F;local&#x2F;gcc49&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Please note that you may need to use &lt;code&gt;-static-libstdc++&lt;&#x2F;code&gt; and
&lt;code&gt;-static-libgcc&lt;&#x2F;code&gt; options when linking your executable file! See the
proper documentation of &lt;code&gt;gcc&lt;&#x2F;code&gt; to read more about characteristics of
these options.&lt;&#x2F;p&gt;
&lt;!-- vim:set ft=markdown: --&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Defeating NAT with reverse SSH proxies</title>
        <published>2014-07-07T00:00:00+00:00</published>
        <updated>2014-07-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/defeating-nat-with-reverse-ssh-proxies.html/"/>
        <id>https://anadoxin.org/blog/defeating-nat-with-reverse-ssh-proxies.html/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/defeating-nat-with-reverse-ssh-proxies.html/">&lt;p&gt;Having a public IP is not as popular as 10 years ago. In earlier days the user
could pay extra cash for this useful service, but now it&#x27;s often an option that is
simply not for sale. Is it possible to access your home network, when this
network sits behind countless NAT layers?&lt;&#x2F;p&gt;
&lt;p&gt;Short answer is &lt;em&gt;yes&lt;&#x2F;em&gt;, but you need to control an external server with public IP
capability, preferably with a fast network connection. You could use some kind
of a personal VPS, which are not as expensive as they were few years ago.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s assume that you have a remote host &lt;code&gt;R&lt;&#x2F;code&gt;, a home network &lt;code&gt;H&lt;&#x2F;code&gt;, and a computer
at work &lt;code&gt;W&lt;&#x2F;code&gt;, from which you&#x27;d like to connect to the home network &lt;code&gt;H&lt;&#x2F;code&gt;, to start
the download of latest episode of &lt;em&gt;Game of Thrones&lt;&#x2F;em&gt;, so it&#x27;ll be ready when
you&#x27;ll get home. ;) Of course I&#x27;m assuming that &lt;code&gt;H&lt;&#x2F;code&gt; and &lt;code&gt;R&lt;&#x2F;code&gt; are running Linux
(or a different, a posix-ly unix-ish, variant). On Windows you may get away with
downloading some binaries like &lt;code&gt;ssh.exe&lt;&#x2F;code&gt;, but I haven&#x27;t got a chance of testing
this approach.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;theory&quot;&gt;Theory&lt;&#x2F;h2&gt;
&lt;p&gt;The plan is:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Running the &lt;code&gt;ssh&lt;&#x2F;code&gt; command from &lt;code&gt;H&lt;&#x2F;code&gt;, that connects to &lt;code&gt;R&lt;&#x2F;code&gt;, to port &lt;code&gt;22&lt;&#x2F;code&gt;,
specifying the remote proxy port &lt;code&gt;19500&lt;&#x2F;code&gt; (it&#x27;s an arbitrary number, choose
another if you&#x27;d like).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Then, with this connection active, you can connect from &lt;code&gt;W&lt;&#x2F;code&gt; to &lt;code&gt;R&lt;&#x2F;code&gt; to port
&lt;code&gt;19500&lt;&#x2F;code&gt;. &lt;code&gt;ssh&lt;&#x2F;code&gt; on the &lt;code&gt;R&lt;&#x2F;code&gt; will forward any packet sent to port &lt;code&gt;19500&lt;&#x2F;code&gt; to &lt;code&gt;H&lt;&#x2F;code&gt;
automatically.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;defeating-nat-with-reverse-ssh-proxies.html&#x2F;sshflow.png&quot; alt=&quot;Flowchart&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This will result in having a connection initiated by &lt;code&gt;W&lt;&#x2F;code&gt; to the home network
&lt;code&gt;H&lt;&#x2F;code&gt;, with &lt;code&gt;R&lt;&#x2F;code&gt; machine serving as a proxy. It may be not what you want if you
want to play games, but for remote administation it works OK.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;practice&quot;&gt;Practice&lt;&#x2F;h2&gt;
&lt;p&gt;For example purposes, let&#x27;s use a host with the name
&lt;strong&gt;yourproxy.externalvps.com&lt;&#x2F;strong&gt;, which uses port 19500.&lt;&#x2F;p&gt;
&lt;p&gt;They say that &lt;em&gt;the commandline is worth a thousand images&lt;&#x2F;em&gt;, so:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# STEP 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[H]OME home $ ssh -R 19500:localhost:22 yourproxy.externalvps.com&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[H]OME Enter ssh password: (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;...&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# STEP 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[W]ORK work $ ssh yourproxy.externalvps.com&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[W]ORK Enter ssh password: (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;...&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[W]ORK yourproxy $ ssh localhost -p 19500&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[W]ORK Enter ssh password: (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;...&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[W]ORK home $ _&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;automatization&quot;&gt;Automatization&lt;&#x2F;h2&gt;
&lt;p&gt;You can use &lt;em&gt;public key authentication&lt;&#x2F;em&gt; to disable the password-based
protection. First, generate your public key for &lt;code&gt;H&lt;&#x2F;code&gt; machine by using &lt;code&gt;ssh-keygen&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[H]OME $ ssh-keygen -t rsa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[H]OME ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then, copy the &lt;code&gt;~&#x2F;.ssh&#x2F;id_rsa.pub&lt;&#x2F;code&gt; file to the &lt;code&gt;R&lt;&#x2F;code&gt; host, and append it to its
&lt;code&gt;~&#x2F;.ssh&#x2F;authorized_keys&lt;&#x2F;code&gt; file:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[R]EMOTE $ cat id_rsa-home.pub &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;gt;&amp;gt; ~&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;.ssh&#x2F;authorized_keys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;WARNING&lt;&#x2F;em&gt;: make sure you&#x27;re using &lt;code&gt;&amp;gt;&amp;gt;&lt;&#x2F;code&gt;, not &lt;code&gt;&amp;gt;&lt;&#x2F;code&gt;!&lt;&#x2F;p&gt;
&lt;p&gt;You should now be able to perform &lt;em&gt;step 1&lt;&#x2F;em&gt; without entering the password to
&lt;code&gt;yourproxy.externalvps.com&lt;&#x2F;code&gt;. This should suit automated scripts, invoked at
system startup, or periodically from your WAN router!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;router-setup&quot;&gt;Router setup&lt;&#x2F;h2&gt;
&lt;p&gt;Every router is different, but most of them contain the &lt;code&gt;BusyBox&lt;&#x2F;code&gt; binary, along
with the &lt;code&gt;dropbear&lt;&#x2F;code&gt; ssh server &amp;amp; client. One thing to note is that &lt;code&gt;dropbear&lt;&#x2F;code&gt;
expects the private key to be stored in its private dropbear format, so you need
to create the private key by using &lt;code&gt;dropbearkey&lt;&#x2F;code&gt; instead of &lt;code&gt;ssh-keygen&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;router&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; dropbearkey&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; rsa&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; id_rsa.dropbear&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# dropbearkey -t rsa -f example&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Will&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 1024&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; bit rsa secret key to &amp;#39;id_rsa.dropbear&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Generating&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; key, this may take a while...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; key portion is:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;ssh-rsa&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; AAAAB3NzaC1yc2EAAAADAQABAAAAgwCh2w0Xv&#x2F;5n7XldpdHo3XQ5VPKZbybsfVUGnYK9uwK294A4Y&#x2F;R8IzSw8vuwZ+Ld9X+N7eQ7aN2H2Ez&#x2F;3TYGHMHoCWnEFhNHmsxJ3LQCtsNm9fBOl58YoE4xGnZHQ1Ig3E2ee&#x2F;j8Xi2tcKdrzE+hKQcoQ0FR2A+HqkUy7Z6TjCd3nIvH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;root@router&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Fingerprint:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; md5 be:5f:34:27:a0:4c:9f:20:f9:bc:7b:f1:f9:19:85:d7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You need to append the line below &lt;code&gt;Public key portion is:&lt;&#x2F;code&gt; to the
&lt;code&gt;authorized_keys&lt;&#x2F;code&gt; file on the &lt;code&gt;R&lt;&#x2F;code&gt; host. Then, by using this commandline from the
router:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;ssh&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -R&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; 19500:localhost:22&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -N -i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &#x2F;jffs&#x2F;id_rsa.dropbear user@yourproxy.externalvps.com&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;you will be able to create a &lt;em&gt;step 1&lt;&#x2F;em&gt; reverse proxy connection from your router
to the &lt;code&gt;R&lt;&#x2F;code&gt; host.&lt;&#x2F;p&gt;
&lt;p&gt;After creating the connection from &lt;code&gt;W&lt;&#x2F;code&gt; to &lt;code&gt;yourproxy.externalvps.com&lt;&#x2F;code&gt;&#x27;s port &lt;code&gt;19500&lt;&#x2F;code&gt; (but
remember, you need to connect to it through &lt;code&gt;localhost&lt;&#x2F;code&gt;), you will connect to
your router. From your router, it should be easy to access your box by just
&lt;code&gt;ssh&lt;&#x2F;code&gt;&#x27;ing on it.&lt;&#x2F;p&gt;
&lt;p&gt;Of course, you can also go even further than that:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;defeating-nat-with-reverse-ssh-proxies.html&#x2F;tomato-wanup.png&quot; alt=&quot;Screenshot from Tomato panel&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In &lt;code&gt;Tomato&lt;&#x2F;code&gt; firmware, you can create a script that will be executed on startup.
&lt;code&gt;&#x2F;jffs&lt;&#x2F;code&gt; partition can be setup to persist between router restarts, so you can
put your scripts there. Consult the documentation if you want to know more about
both the &lt;code&gt;&#x2F;jffs&lt;&#x2F;code&gt; partition and this particular Tomato administration option.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>PCI device enumeration using ports 0xCF8, 0xCFC</title>
        <published>2014-07-02T00:00:00+00:00</published>
        <updated>2014-07-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/pci-device-enumeration-using-ports-0xcf8-0xcfc.html/"/>
        <id>https://anadoxin.org/blog/pci-device-enumeration-using-ports-0xcf8-0xcfc.html/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/pci-device-enumeration-using-ports-0xcf8-0xcfc.html/">&lt;p&gt;This is how you can enumerate your PCI devices by using ports &lt;code&gt;0xCF8&lt;&#x2F;code&gt; and
&lt;code&gt;0xCFC&lt;&#x2F;code&gt;. Please note that this code is intended to run from the privileged mode
(&lt;code&gt;ring 0&lt;&#x2F;code&gt;), thus it&#x27;s compiled as a kernel module for Linux.&lt;&#x2F;p&gt;
&lt;p&gt;The PCI specification can be downloaded from &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;tesla.desy.de&#x2F;doocs&#x2F;hardware&#x2F;pci&#x2F;pci21.pdf&quot;&gt;here&lt;&#x2F;a&gt; (or, alternatively, you
can search &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;duckduckgo.com&#x2F;?q=pci21.pdf&quot;&gt;here&lt;&#x2F;a&gt; if the previous link is no longer working).&lt;&#x2F;p&gt;
&lt;p&gt;The example below will read the &lt;code&gt;uint32_t&lt;&#x2F;code&gt; from the address of &lt;code&gt;0&lt;&#x2F;code&gt; (which is the
last argument of the &lt;code&gt;r_pci_32&lt;&#x2F;code&gt; function) of this structure:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;pci-device-enumeration-using-ports-0xcf8-0xcfc.html&#x2F;pci-cs.png&quot; alt=&quot;PCI Configuration Space structure&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is the PCI Configuration Space structure, which holds basic information
about the PCI device.&lt;&#x2F;p&gt;
&lt;p&gt;Here is the source code of the module:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;linux&#x2F;kernel.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;linux&#x2F;init.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;linux&#x2F;module.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;asm&#x2F;io.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; u32 PCI_ENABLE_BIT     &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;= 0x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;80000000&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; u32 PCI_CONFIG_ADDRESS &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;= 0x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;CF8&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span&gt; u32 PCI_CONFIG_DATA    &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;= 0x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;CFC&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;&#x2F; func - 0-7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;&#x2F; slot - 0-31&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;&#x2F; bus - 0-255&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;u32 &lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;r_pci_32&lt;&#x2F;span&gt;&lt;span&gt;(u8 &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;bus&lt;&#x2F;span&gt;&lt;span&gt;, u8 &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;device&lt;&#x2F;span&gt;&lt;span&gt;, u8 &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;func&lt;&#x2F;span&gt;&lt;span&gt;, u8 &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;pcireg&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;        &#x2F;&#x2F; unsigned long flags;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;        &#x2F;&#x2F; local_irq_save(flags)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;        outl&lt;&#x2F;span&gt;&lt;span&gt;(PCI_ENABLE_BIT &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; (bus &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt; (device &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt; (func &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt; (pcireg &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;), PCI_CONFIG_ADDRESS);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        u32 ret &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; inl&lt;&#x2F;span&gt;&lt;span&gt;(PCI_CONFIG_DATA);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;        &#x2F;&#x2F; local_irq_restore(flags);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; ret;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;static&lt;&#x2F;span&gt;&lt;span&gt; __init &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; init_pcilist&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        u8 bus, device, func;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        u32 data;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt;(bus &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; bus &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;!= 0x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;ff&lt;&#x2F;span&gt;&lt;span&gt;; bus&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                for&lt;&#x2F;span&gt;&lt;span&gt;(device &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; device &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;; device&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                        for&lt;&#x2F;span&gt;&lt;span&gt;(func &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; func &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;; func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                data &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; r_pci_32&lt;&#x2F;span&gt;&lt;span&gt;(bus, device, func,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                                if&lt;&#x2F;span&gt;&lt;span&gt;(data &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;!= 0x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;ffffffff&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;                                        printk&lt;&#x2F;span&gt;&lt;span&gt;(KERN_INFO &lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;bus &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;%d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;, device &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;%d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;, func &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;%d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;: vendor=0x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;%08x\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, bus, device, func, data);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;static&lt;&#x2F;span&gt;&lt;span&gt; __exit &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; exit_pcilist&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;module_init&lt;&#x2F;span&gt;&lt;span&gt;(init_pcilist);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;module_exit&lt;&#x2F;span&gt;&lt;span&gt;(exit_pcilist);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This code is not adapted for production code, because if suffers from race
conditions. It doesn&#x27;t lock the access to the ports, so the risk of using it is
that you will end up with some device in unspecified state. In a controlled,
home environment (virtual machine) it works quite nicely though.&lt;&#x2F;p&gt;
&lt;p&gt;The locking part could be probably implemented by using:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;raw_spin_lock_irqsave&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; pci_config&lt;&#x2F;span&gt;&lt;span&gt;, lock, ...);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It should also temporarily disable interrupts. You could probably also lock the
access by using &lt;code&gt;request_region&lt;&#x2F;code&gt;. But, instead of directly reading those ports
by &lt;code&gt;outl&lt;&#x2F;code&gt; and &lt;code&gt;inl&lt;&#x2F;code&gt;, it&#x27;s better to use Linux&#x27; mechanism of reading PCI data,
which lives insite the &lt;code&gt;pci_bus&lt;&#x2F;code&gt; object in the &lt;code&gt;ops&lt;&#x2F;code&gt; field. More information
about this mechanism can be found inside the &lt;code&gt;arch&#x2F;x86&#x2F;pci&#x2F;direct.c&lt;&#x2F;code&gt; file.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>D-Bus, UDisks and Glibmm bindings</title>
        <published>2014-07-01T00:00:00+00:00</published>
        <updated>2014-07-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/dbus-udisks-and-glibmm-bindings.html/"/>
        <id>https://anadoxin.org/blog/dbus-udisks-and-glibmm-bindings.html/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/dbus-udisks-and-glibmm-bindings.html/">&lt;p&gt;One day I was having a problem with simple D-Bus concept. I was using Glibmm
D-Bus bindings (&lt;code&gt;Gio::DBus&lt;&#x2F;code&gt; namespace) to access the &lt;code&gt;UDisks&lt;&#x2F;code&gt; interface. I
wanted to read some attributes of every hard disk found in the system, so first
I needed to enumerate all disks that &lt;code&gt;UDisks&lt;&#x2F;code&gt; was reporting, like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Glib&lt;&#x2F;span&gt;&lt;span&gt;::RefPtr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Gio&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;DBus&lt;&#x2F;span&gt;&lt;span&gt;::Connection&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; bus;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    using namespace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Glib&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    using namespace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Gio&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    Glib&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    Gio&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bus &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; DBus&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Connection&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;get_sync&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Gio&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;DBus&lt;&#x2F;span&gt;&lt;span&gt;::BUS_TYPE_SYSTEM);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    RefPtr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;DBus&lt;&#x2F;span&gt;&lt;span&gt;::Proxy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; udisks_proxy &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; DBus&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Proxy&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;create_sync&lt;&#x2F;span&gt;&lt;span&gt;(bus,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;org.freedesktop.UDisks&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;&#x2F;org&#x2F;freedesktop&#x2F;UDisks&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;org.freedesktop.UDisks&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    VariantContainerBase devices_variant &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; udisks_proxy-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;call_sync&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;EnumerateDevices&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    VariantIter&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; iterator&lt;&#x2F;span&gt;&lt;span&gt;(devices_variant.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;get_child&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Variant&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;ustring&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; var;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt;(iterator.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;next_value&lt;&#x2F;span&gt;&lt;span&gt;(var)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ustring name &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; var.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;        LOG&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;device: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;%s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, name.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;c_str&lt;&#x2F;span&gt;&lt;span&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;        process_device&lt;&#x2F;span&gt;&lt;span&gt;(name);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This seemed to work OK, because &lt;code&gt;call_sync()&lt;&#x2F;code&gt; returned a &lt;code&gt;VariantContainerBase&lt;&#x2F;code&gt;,
which holds the &lt;code&gt;(ao)&lt;&#x2F;code&gt; object, which basically is: &lt;em&gt;one struct of an array of
object paths&lt;&#x2F;em&gt;. From the documentation I read that the &lt;em&gt;object path&lt;&#x2F;em&gt; type is
handled in the same way as a &lt;em&gt;string&lt;&#x2F;em&gt; type, that&#x27;s why the untyped &lt;code&gt;VariantBase&lt;&#x2F;code&gt;
that is created during &lt;code&gt;get_child(0)&lt;&#x2F;code&gt; allows itself to be casted into
&lt;code&gt;Variant&amp;lt;ustring&amp;gt;&lt;&#x2F;code&gt; object. Using this parametrized &lt;code&gt;Variant&lt;&#x2F;code&gt;, it&#x27;s trivial to
extract the string by using &lt;code&gt;var.get()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;But then I was trying to read some stuff (in that particular case, the
&lt;code&gt;NativePath&lt;&#x2F;code&gt; attribute) from the attributes of each drive using this method:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; process_device&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Glib&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;ustring&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; objpath&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;	using namespace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Glib&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;	using namespace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Gio&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	RefPtr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;DBus&lt;&#x2F;span&gt;&lt;span&gt;::Proxy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; attrs &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; DBus&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Proxy&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;create_sync&lt;&#x2F;span&gt;&lt;span&gt;(bus,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;org.freedesktop.UDisks&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, objpath,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;org.freedesktop.DBus.Properties&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;	std&lt;&#x2F;span&gt;&lt;span&gt;::vector&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;VariantBase&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; args;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	args.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Variant&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;ustring&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;create&lt;&#x2F;span&gt;&lt;span&gt;(objpath));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	args.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Variant&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;ustring&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;create&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;NativePath&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	VariantContainerBase data &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; attrs-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;call_sync&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;Get&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; VariantContainerBase&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;create_tuple&lt;&#x2F;span&gt;&lt;span&gt;(args));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;	LOG&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;return type: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;%s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, data.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;get_type_string&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;c_str&lt;&#x2F;span&gt;&lt;span&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The problem was that the &lt;code&gt;VariantContainerBase&lt;&#x2F;code&gt; object contained the &lt;code&gt;(v)&lt;&#x2F;code&gt;
signature. This means that the object is &lt;em&gt;variant&lt;&#x2F;em&gt;, so I couldn&#x27;t cast it to
anything.&lt;&#x2F;p&gt;
&lt;p&gt;Introspection of the attributes showed that &lt;code&gt;NativePath&lt;&#x2F;code&gt; was holding a &lt;em&gt;string&lt;&#x2F;em&gt;
value. So why the &lt;code&gt;call_sync()&lt;&#x2F;code&gt; method was returning an object of a variant
type? How the &lt;code&gt;NativePath&lt;&#x2F;code&gt; attribute could be read, without using &lt;code&gt;get_data()&lt;&#x2F;code&gt;
method and without doing &lt;code&gt;memcpy&lt;&#x2F;code&gt; of the data into manually allocated buffer?&lt;&#x2F;p&gt;
&lt;p&gt;The solution would suggest that probably it was a bug in &lt;code&gt;glibmm&lt;&#x2F;code&gt;&#x27;s bindings.&lt;&#x2F;p&gt;
&lt;p&gt;Instead of calling &lt;code&gt;VariantContainerBase&lt;&#x2F;code&gt;&#x27;s &lt;code&gt;get_child(0)&lt;&#x2F;code&gt;, a proper way is to
call a direct &lt;code&gt;glib&lt;&#x2F;code&gt; function: &lt;code&gt;g_variant_get_child()&lt;&#x2F;code&gt;, like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;GVariant &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;output;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;g_variant_get_child&lt;&#x2F;span&gt;&lt;span&gt;(data.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;gobj&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;v&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; output&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It will properly set the &lt;code&gt;output&lt;&#x2F;code&gt;&#x27;s variant type to one that&#x27;s insive &lt;code&gt;v&lt;&#x2F;code&gt; (in my
case it will set the type of &lt;code&gt;output&lt;&#x2F;code&gt; to &lt;code&gt;s&lt;&#x2F;code&gt;). After this, when I got the remote
data in the &lt;code&gt;s&lt;&#x2F;code&gt; type, I could cast it to &lt;code&gt;Variant&amp;lt;ustring&amp;gt;&lt;&#x2F;code&gt; type like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Variant&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Glib&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;ustring&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; item&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;output&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Glib&lt;&#x2F;span&gt;&lt;span&gt;::ustring text &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; item.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;since, fortunately, &lt;code&gt;Variant&lt;&#x2F;code&gt;&#x27;s constructor accepts the old, glib-ish &lt;code&gt;GVariant *&lt;&#x2F;code&gt; type.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m still not sure whether it was a bug, or a feature.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Friendly GDB</title>
        <published>2013-07-11T00:00:00+00:00</published>
        <updated>2013-07-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/friendly-gdb.html/"/>
        <id>https://anadoxin.org/blog/friendly-gdb.html/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/friendly-gdb.html/">&lt;p&gt;The &lt;code&gt;gdb&lt;&#x2F;code&gt; debugger is a very old application, used widely in the past, when a
computer was not yet a part of every house&#x27;s inventory. Contrary to what many
people say, it&#x27;s very usable even today, mainly because of its extensibility,
which lets the user to adapt it to his&#x2F;hers specific needs.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s quite easy to add custom &lt;em&gt;renderers&lt;&#x2F;em&gt; to &lt;code&gt;gdb&lt;&#x2F;code&gt;. They are a piece of code
that convert data types into human readable form, so it&#x27;s easy to understand
given type by just looking at the data dump.&lt;&#x2F;p&gt;
&lt;p&gt;Here is an example data dump of the &lt;code&gt;QString&lt;&#x2F;code&gt; structure (it&#x27;s a container for
strings in the Qt Framework), created by using the &lt;code&gt;print&lt;&#x2F;code&gt; command:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;friendly-gdb.html&#x2F;qstring1.png&quot; alt=&quot;screenshot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As you can see, you can&#x27;t see much ;). Maybe this kind of information is useful
for a Qt developer, which is debugging the functionality of &lt;code&gt;QString&lt;&#x2F;code&gt; structure,
but our case is completely different. The solution for this problem is to tell
&lt;code&gt;gdb&lt;&#x2F;code&gt; what kind of information we seek and make it display only these fields
which match our interest.&lt;&#x2F;p&gt;
&lt;p&gt;The first step is to acquire the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;quickgit.kde.org&#x2F;?p=kdevelop.git&amp;amp;a=tree&amp;amp;h=2276bc198f437a85a1bbfa5cbbd3cb33e6247fc8&amp;amp;hb=5d22a60748bb8069a7e8f7dd0549407d4269e920&amp;amp;f=debuggers%2Fgdb%2Fprinters&quot;&gt;Qt renderer pack&lt;&#x2F;a&gt;. You can get it from i.e. KDevelop&#x27;s
repository. It was written by Niko Sams, and it definitely does the job well. We
have to use the &lt;code&gt;qt4.py&lt;&#x2F;code&gt; file, which contains the code to convert raw structure
dump into more eye-friendly notation. As you can also probably see, the same
directory in the repository also contains another file named &lt;code&gt;libstdcxx.py&lt;&#x2F;code&gt;
which does the same thing for classes from &lt;code&gt;std&lt;&#x2F;code&gt; library (standard C++ library),
like &lt;code&gt;std::string&lt;&#x2F;code&gt;, &lt;code&gt;std::map&lt;&#x2F;code&gt;, and others. These files can be copied into any
directory. For example, here seems to be a good spot for it:
&lt;code&gt;&#x2F;usr&#x2F;share&#x2F;gdb&#x2F;auto-load&#x2F;usr&#x2F;lib&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Step two is to create the &lt;code&gt;~&#x2F;.gdbinit&lt;&#x2F;code&gt; file. It will be automatically loaded
during every invocation of &lt;code&gt;gdb&lt;&#x2F;code&gt;. Here&#x27;s what you can put into it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; sys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sys.path.insert(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;#39;&#x2F;usr&#x2F;share&#x2F;gdb&#x2F;auto-load&#x2F;usr&#x2F;lib&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; qt4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; register_qt4_printers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; libstdcxx&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; register_libstdcxx_printers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;register_qt4_printers(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;register_libstdcxx_printers(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;set&lt;&#x2F;span&gt;&lt;span&gt; auto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;load local&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;gdbinit on&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;set print&lt;&#x2F;span&gt;&lt;span&gt; pretty&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;set&lt;&#x2F;span&gt;&lt;span&gt; auto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;load safe&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;path&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span&gt;usr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;share&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;gdb&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;auto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;load&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you&#x27;ll get errors after invoking &lt;code&gt;gdb&lt;&#x2F;code&gt;, you may want to check if:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Your path is correct, contains both &lt;code&gt;.py&lt;&#x2F;code&gt; files (&lt;code&gt;qt4.py&lt;&#x2F;code&gt; and &lt;code&gt;libstdcxx.py&lt;&#x2F;code&gt;),&lt;&#x2F;li&gt;
&lt;li&gt;The python interpreter is correctly configured (is it v2.7? or maybe v3.0?),&lt;&#x2F;li&gt;
&lt;li&gt;You can also review your security settings related to initialization script path
whitelisting ({SafePath}[related link]).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;If no errors will occur, the next time you will use &lt;code&gt;print&lt;&#x2F;code&gt; command on a
supported data type, it will display something that is more friendly than ever
before:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;friendly-gdb.html&#x2F;qstring2.png&quot; alt=&quot;renderers in action&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Much better! Other examples:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;example-1&quot;&gt;Example 1&lt;&#x2F;h2&gt;
&lt;p&gt;Without printers:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(gdb) p strings&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$1 = {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  _M_t = {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _M_impl = {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &amp;lt;std::allocator&amp;lt;std::_Rb_tree_node&amp;lt;std::pair&amp;lt;QString const, int&amp;gt; &amp;gt; &amp;gt;&amp;gt; = {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &amp;lt;__gnu_cxx::new_allocator&amp;lt;std::_Rb_tree_node&amp;lt;std::pair&amp;lt;QString const, int&amp;gt; &amp;gt; &amp;gt;&amp;gt; = {&amp;lt;No data fields&amp;gt;}, &amp;lt;No data fields&amp;gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      members of std::_Rb_tree&amp;lt;QString, std::pair&amp;lt;QString const, int&amp;gt;, std::_Select1st&amp;lt;std::pair&amp;lt;QString const, int&amp;gt; &amp;gt;, std::less&amp;lt;QString&amp;gt;, std::allocator&amp;lt;std::pair&amp;lt;QString const, int&amp;gt; &amp;gt; &amp;gt;::_Rb_tree_impl&amp;lt;std::less&amp;lt;QString&amp;gt;, false&amp;gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      _M_key_compare = {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &amp;lt;std::binary_function&amp;lt;QString, QString, bool&amp;gt;&amp;gt; = {&amp;lt;No data fields&amp;gt;}, &amp;lt;No data fields&amp;gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      _M_header = {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _M_color = std::_S_red,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _M_parent = 0x6040c0,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _M_left = 0x604050,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _M_right = 0x604140&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      _M_node_count = 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With printers:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(gdb) p strings&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$1 = std::map with 3 elements = {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [&amp;quot;hello world&amp;quot;] = 1,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [&amp;quot;test&amp;quot;] = 2,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [&amp;quot;test2&amp;quot;] = 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;example-2&quot;&gt;Example 2&lt;&#x2F;h2&gt;
&lt;p&gt;Without printers:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(gdb) p v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$1 = {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &amp;lt;std::_Vector_base&amp;lt;int, std::allocator&amp;lt;int&amp;gt; &amp;gt;&amp;gt; = {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _M_impl = {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &amp;lt;std::allocator&amp;lt;int&amp;gt;&amp;gt; = {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &amp;lt;__gnu_cxx::new_allocator&amp;lt;int&amp;gt;&amp;gt; = {&amp;lt;No data fields&amp;gt;}, &amp;lt;No data fields&amp;gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      members of std::_Vector_base&amp;lt;int, std::allocator&amp;lt;int&amp;gt; &amp;gt;::_Vector_impl:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      _M_start = 0x6051c0,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      _M_finish = 0x6051cc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      _M_end_of_storage = 0x6051d0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }, &amp;lt;No data fields&amp;gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With printers:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(gdb) p v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$1 = std::vector of length 3, capacity 4 = {1, 2, 3}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;example-3&quot;&gt;Example 3&lt;&#x2F;h2&gt;
&lt;p&gt;Without printers:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(gdb) p strmap&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$1 = {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    d = 0x6061f0,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    e = 0x6061f0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With printers:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(gdb) p strmap&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$1 = QMap&amp;lt;std::basic_string&amp;lt;char, std::char_traits&amp;lt;char&amp;gt;, std::allocator&amp;lt;char&amp;gt; &amp;gt;, std::basic_string&amp;lt;char, std::char_traits&amp;lt;char&amp;gt;, std::allocator&amp;lt;char&amp;gt; &amp;gt;&amp;gt; = {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [&amp;quot;a&amp;quot;] = &amp;quot;b&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [&amp;quot;b&amp;quot;] = &amp;quot;c&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [&amp;quot;c&amp;quot;] = &amp;quot;d&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Okay, the last part could be better (more condensed), but having the access to
the source code you can just fix it for yourself. And still it&#x27;s better than the
un-friendly version!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Accessing libvirt&#x27;s virtual machines from a script</title>
        <published>2013-01-19T00:00:00+00:00</published>
        <updated>2013-01-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/accessing-libvirts-virtual-machines-from-a-script.html/"/>
        <id>https://anadoxin.org/blog/accessing-libvirts-virtual-machines-from-a-script.html/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/accessing-libvirts-virtual-machines-from-a-script.html/">&lt;p&gt;Everyone who has ever used the &lt;code&gt;libvirt&lt;&#x2F;code&gt; library probably knows that it&#x27;s
impossible to use it from scripts without previous authorization in the &lt;code&gt;polkit&lt;&#x2F;code&gt;
daemon.&lt;&#x2F;p&gt;
&lt;p&gt;This complicates things when the user would like to create a script to control
some virtual machines. The script that is probably configured to be invoked
periodically is running from the context of normal user. Popping up the &lt;code&gt;polkit&lt;&#x2F;code&gt;
messagebox which requires to enter authorization credentials at every execution
of this script is probably not what most people would like to have.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;accessing-libvirts-virtual-machines-from-a-script.html&#x2F;pkexec.png&quot; alt=&quot;screenshot from &amp;#39;pkexec ls&amp;#39;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This problem can be fixed by creating two polkit rules. There is however some
confusion about the format of the files which hold the rules.&lt;&#x2F;p&gt;
&lt;p&gt;Until &lt;code&gt;polkit&lt;&#x2F;code&gt; version &lt;code&gt;106&lt;&#x2F;code&gt; it was possible to create the &lt;code&gt;pkla&lt;&#x2F;code&gt; descriptor
(&lt;em&gt;polkit local authority&lt;&#x2F;em&gt; file), which was a simple &lt;code&gt;.ini&lt;&#x2F;code&gt; file. It was possible
to put the rules in there, by using the simple &lt;code&gt;INI&lt;&#x2F;code&gt; file format. However, since
version &lt;code&gt;106&lt;&#x2F;code&gt;, &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;cgit.freedesktop.org&#x2F;polkit&#x2F;commit&#x2F;?id=0f830c76048229895164837f8ce01869d88a2616&#x2F;&quot;&gt;it&#x27;s not possible&lt;&#x2F;a&gt; anymore, because this version forces the use of
JavaScript language to create new &lt;code&gt;polkit&lt;&#x2F;code&gt; rules. All of your existing rules you
have written until now are expired, and need to be rewritten to the new
JavaScript syntax.&lt;&#x2F;p&gt;
&lt;p&gt;To allow authorization of the &lt;code&gt;libvirt&lt;&#x2F;code&gt; library in &lt;code&gt;polkit&lt;&#x2F;code&gt;, taking as an
example the &lt;code&gt;virt-manager&lt;&#x2F;code&gt; frontend application, you need to find the proper
action of &lt;code&gt;libvirt&lt;&#x2F;code&gt; &#x27;s polkit rule provider. You can find it by using the
&lt;code&gt;pkaction&lt;&#x2F;code&gt; command:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;2:504&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; for i in `&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;pkaction&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; grep&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; libvirt`&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; do&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; pkaction&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --action-id&lt;&#x2F;span&gt;&lt;span&gt; $i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --verbose&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;org.libvirt.unix.manage:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;  description:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;       Manage local virtualized systems&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;  message:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;           System policy prevents management of local virtualized systems&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;  vendor:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;  vendor_url:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;  icon:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;  implicit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; any:      auth_admin_keep&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;  implicit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; inactive: auth_admin_keep&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;  implicit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; active:   auth_admin_keep&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;org.libvirt.unix.monitor:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;  description:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;       Monitor local virtualized systems&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;  message:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;           System policy prevents monitoring of local virtualized systems&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;  vendor:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;  vendor_url:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;  icon:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;  implicit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; any:      yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;  implicit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; inactive: yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;  implicit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; active:   yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It seems that the &lt;code&gt;org.libvirt.unix.manage&lt;&#x2F;code&gt; action is responsible for allowing
or declining the access to &lt;code&gt;libvirt&lt;&#x2F;code&gt;. This action needs to be used in the
declaration of our directive which defines the authorization permission.&lt;&#x2F;p&gt;
&lt;p&gt;The rules themselves are placed inside the &lt;code&gt;&#x2F;etc&#x2F;polkit-1&#x2F;rules.d&lt;&#x2F;code&gt; directory (or
&lt;code&gt;&#x2F;usr&#x2F;share&#x2F;polkit-1&#x2F;rules.d&lt;&#x2F;code&gt;). The default action (on ArchLinux), in the time
of writing this post, is located inside the &lt;code&gt;50-default.rules&lt;&#x2F;code&gt; file, but we
should create a new file, named i.e. &lt;code&gt;50-virtmgr.rules&lt;&#x2F;code&gt;, and put this content
inside the file:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;polkit.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;addRule&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;action&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; subject&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt;(action.id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;org.libvirt.unix.manage&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; subject.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;isInGroup&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;wheel&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span&gt; polkit.Result.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;YES&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which means, more or less: if currently evaluating action is named
&lt;code&gt;org.libvirt.unix.manage&lt;&#x2F;code&gt; and the user, who asks for authorization, belongs to
the &lt;code&gt;wheel&lt;&#x2F;code&gt; system group (see the &lt;code&gt;&#x2F;etc&#x2F;group&lt;&#x2F;code&gt; file), then allow the
authorization. Just remember to add yourself to the &lt;code&gt;wheel&lt;&#x2F;code&gt; group before using
this rule.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Compiling glibmm on Windows</title>
        <published>2012-11-02T00:00:00+00:00</published>
        <updated>2012-11-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/compiling-glibmm-on-windows.html/"/>
        <id>https://anadoxin.org/blog/compiling-glibmm-on-windows.html/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/compiling-glibmm-on-windows.html/">&lt;p&gt;Here is a short list of steps which need to be taken to successfully install the
&lt;code&gt;glibmm&lt;&#x2F;code&gt; library, using gcc 4.7.1, in Windows environment. Use-case scenario for
this install would be to use a virtual machine, not a physical one. In the case
anyone would choose to use &lt;em&gt;real&lt;&#x2F;em&gt; system, all configuration steps should be
changed to include the &lt;code&gt;--prefix&lt;&#x2F;code&gt; option, to avoid creating mess in the system.
Also, by using prefixes you will be able to remove everything later by only
deleting one directory.&lt;&#x2F;p&gt;
&lt;p&gt;Primary requirements are:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;MinGW (&quot;MinGW Shell&quot;),&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; title=&quot;TDM-GCC&quot; href=&quot;http:&#x2F;&#x2F;tdm-gcc.tdragon.net&quot;&gt;TDM-GCC&lt;&#x2F;a&gt;, which was v4.7.1 in the time of writing this post.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;step-1-zlib&quot;&gt;Step 1: zlib&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; title=&quot;Zlib v1.2.7&quot; href=&quot;http:&#x2F;&#x2F;zlib.net&quot;&gt;Zlib&lt;&#x2F;a&gt;, which compiles normally, according to the instructions shown on
the screen:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; make&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; win32&#x2F;Makefile.gcc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;step-2-iconv&quot;&gt;Step 2: iconv&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; title=&quot;Iconv v1.14&quot; href=&quot;http:&#x2F;&#x2F;ftp.gnu.org&#x2F;pub&#x2F;gnu&#x2F;libiconv&#x2F;libiconv-1.14.tar.gz&quot;&gt;Iconv&lt;&#x2F;a&gt;, also installs normally:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; .&#x2F;configure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; make&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; make install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;step-3-gettext&quot;&gt;Step 3: gettext&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; title=&quot;gettext v0.18.1.1&quot; href=&quot;http:&#x2F;&#x2F;ftp.gnu.org&#x2F;pub&#x2F;gnu&#x2F;gettext&#x2F;gettext-0.18.1.1.tar.gz&quot;&gt;Gettext&lt;&#x2F;a&gt;. First, the configure step needs to be taken:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; CPPFLAGS=&amp;quot;-I &#x2F;usr&#x2F;local&#x2F;include&amp;quot; LDFLAGS=&amp;quot;-L&#x2F;usr&#x2F;local&#x2F;lib&amp;quot; .&#x2F;configure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you&#x27;re getting any errors about suporfluous space between &lt;code&gt;-L&lt;&#x2F;code&gt; and
&lt;code&gt;&#x2F;usr&#x2F;local&#x2F;lib&lt;&#x2F;code&gt;, you need to manually amend &lt;code&gt;Makefile&lt;&#x2F;code&gt; and remove this space
from the file. You can use this oneliner to accomplish this task:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; find .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -iname&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;#39;Makefile&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -exec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; sed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;{}&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;#39;s&#x2F;-L &#x2F;-L&#x2F;g&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; \;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It should fix the problem. Last step is to run the compilation and installation,
without further complications:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; make&lt;&#x2F;span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; make&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;step-4-glib&quot;&gt;Step 4: glib&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; title=&quot;glib 2.28.8&quot; href=&quot;http:&#x2F;&#x2F;ftp.gnome.org&#x2F;pub&#x2F;gnome&#x2F;sources&#x2F;glib&#x2F;2.28&#x2F;glib-2.28.8.tar.bz2&quot;&gt;Glib&lt;&#x2F;a&gt;. All you need to do is to inform &lt;code&gt;configure&lt;&#x2F;code&gt; script about the existence
of library dependencies. In the place of &lt;code&gt;&#x2F;c&#x2F;gnome&lt;&#x2F;code&gt;, insert your own path, where
sources of the dependencies are located.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; CPPFLAGS=&amp;quot;-I &#x2F;c&#x2F;gnome&#x2F;gettext&#x2F;gettext-0.18.1.1&#x2F;gettext-runtime&#x2F;intl -I&#x2F;c&#x2F;gnome&#x2F;zlib&#x2F;zlib-1.2.7&amp;quot; LDFLAGS=&amp;quot;-L&#x2F;c&#x2F;gnome&#x2F;zlib&#x2F;zlib-1.2.7 -L&#x2F;c&#x2F;gnome&#x2F;gettext&#x2F;gettext-0.18.1.1&#x2F;gettext-runtime&#x2F;intl&#x2F;.libs&amp;quot; .&#x2F;configure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; make&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; make install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;step-5-mm-common&quot;&gt;Step 5: mm-common&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;git:&#x2F;&#x2F;git.gnome.org&#x2F;mm-common&quot; title=&quot;mm-common&quot;&gt;mmcommon&lt;&#x2F;a&gt; macro set -- they can be downloaded by &lt;code&gt;git&lt;&#x2F;code&gt;. The &lt;code&gt;configure&lt;&#x2F;code&gt; script
should download any dependencies, so you need to enable networking in your
virtual machine.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; .&#x2F;autogen.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; .&#x2F;configure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --enable-network&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; make&lt;&#x2F;span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; make&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;step-6-pkg-config&quot;&gt;Step 6: pkg-config&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; title=&quot;pkg-config v0.27.1&quot; href=&quot;http:&#x2F;&#x2F;pkgconfig.freedesktop.org&#x2F;releases&#x2F;pkg-config-0.27.1.tar.gz&quot;&gt;PkgConf&lt;&#x2F;a&gt;. Easiest way is to use its internal &lt;code&gt;glib&lt;&#x2F;code&gt; when compiling. The
&lt;code&gt;-march=i486&lt;&#x2F;code&gt; option is required (but you can try to use a higher setting if you
want).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; CFLAGS=&amp;quot;-march=i486&amp;quot; .&#x2F;configure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --with-internal-glib&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; make&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; make install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;step-7-libsigc&quot;&gt;Step 7: libsigc++&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; title=&quot;libsigc++ v2.3.1&quot; href=&quot;http:&#x2F;&#x2F;ftp.gnome.org&#x2F;pub&#x2F;GNOME&#x2F;sources&#x2F;libsigc++&#x2F;2.3&#x2F;libsigc++-2.3.1.tar.xz&quot;&gt;Sigc++&lt;&#x2F;a&gt;. It is an important dependency of &lt;code&gt;glibmm&lt;&#x2F;code&gt;, because it&#x27;s the core of
signal and slot mechanism. The library itself seems to be quite complicated, but
the usage is rather simple. Luckily, the compilation is trivial.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; .&#x2F;configure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; make&lt;&#x2F;span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; make&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;step-8-glibmm&quot;&gt;Step 8: glibmm&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; title=&quot;glibmm v2.28&quot; href=&quot;http:&#x2F;&#x2F;ftp.gnome.org&#x2F;pub&#x2F;GNOME&#x2F;sources&#x2F;glibmm&#x2F;2.28&#x2F;glibmm-2.28.0.tar.bz2&quot;&gt;Glibmm&lt;&#x2F;a&gt;. I suspect that the version of the &lt;code&gt;glibmm&lt;&#x2F;code&gt; library must match the
version of &lt;code&gt;glib&lt;&#x2F;code&gt; ({glib}) from step 4.&lt;&#x2F;p&gt;
&lt;p&gt;First, we need to use &lt;code&gt;autogen.sh&lt;&#x2F;code&gt; while pointing it to the &lt;code&gt;m4&lt;&#x2F;code&gt; macro
collection from &lt;code&gt;mm-common&lt;&#x2F;code&gt; macro set (installed in step 5). Then, we need to
invoke the &lt;code&gt;configure&lt;&#x2F;code&gt; script remembering that TDM-GCC uses the &lt;code&gt;C++11&lt;&#x2F;code&gt; standard
by default. This is the reason why I&#x27;m using the &lt;code&gt;CXXFLAGS&lt;&#x2F;code&gt; environment
variable, where I&#x27;ve used the &lt;code&gt;-std=c++03&lt;&#x2F;code&gt; option, to turn off &lt;code&gt;C++11&lt;&#x2F;code&gt;. I&#x27;m not
sure if this step is necessary -- in case of any errors you should get rid of
this option. Just be aware that C++11 used in tdm-gcc 4.7 breaks some binary
compatibility between the previous, 4.6, version, so i.e. the &lt;code&gt;&amp;lt;list&amp;gt;&lt;&#x2F;code&gt; class in
&lt;code&gt;C++11&lt;&#x2F;code&gt; got some new fields. After succesfull (I hope) compilation, you need to
open up the &lt;code&gt;config.h&lt;&#x2F;code&gt; file and place &lt;code&gt;#undef&lt;&#x2F;code&gt; &#x27;s for these symbols:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;#undef GLIBMM_HAVE_WIDE_STREAM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;#undef GLIBMM_HAVE_ALLOWS_STATIC_INLINE_NPOS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Best would be to use the appropriate places for these directives (just use the
Find option of your favorite text editor).&lt;&#x2F;p&gt;
&lt;p&gt;So, the list of steps:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; ACLOCAL_FLAGS=&amp;quot;-I &#x2F;usr&#x2F;local&#x2F;share&#x2F;aclocal&amp;quot; .&#x2F;autogen.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; CXXFLAGS=&amp;quot;-std=c++03&amp;quot; .&#x2F;configure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# remember about #undef&amp;#39;s!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; make install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For the last &lt;code&gt;make install&lt;&#x2F;code&gt; to work, you need to install the &lt;code&gt;doxygen&lt;&#x2F;code&gt; and
&lt;code&gt;xsltproc&lt;&#x2F;code&gt; packages. The reason for this is that the &lt;code&gt;pkg-config&lt;&#x2F;code&gt; definition
files (&lt;code&gt;.pc&lt;&#x2F;code&gt;) are installed &lt;em&gt;after&lt;&#x2F;em&gt; installing the documentation, which needs to
be generated first. Not the best idea, but probably the sequence was generated
automatically and since it doesn&#x27;t make any problems for anybody, probably noone
really cares about it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;testing&quot;&gt;Testing&lt;&#x2F;h3&gt;
&lt;p&gt;This should do the trick. Now you should have the &lt;code&gt;glibmm&lt;&#x2F;code&gt; library installed,
together with the &lt;code&gt;pkg-config&lt;&#x2F;code&gt; definition files, so compilation of your sources
should work:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; g++ glibmmtest.cpp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; glibmmtest `&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;pkg-config&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --cflags --libs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; glibmm-2.4`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; .&#x2F;glibmmtest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Hello,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; world&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here&#x27;s the source for &lt;code&gt;glibmmtest.cpp&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;stdio.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;lt;glibmm.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; argc&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; char *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;argv&lt;&#x2F;span&gt;&lt;span&gt;[]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;	Glib&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;thread_init&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;	Glib&lt;&#x2F;span&gt;&lt;span&gt;::Mutex m;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;	Glib&lt;&#x2F;span&gt;&lt;span&gt;::ustring testStr &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;Hello, world&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;printf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;%s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, testStr.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;c_str&lt;&#x2F;span&gt;&lt;span&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Linux binfmt subsystem</title>
        <published>2012-06-16T00:00:00+00:00</published>
        <updated>2012-06-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://anadoxin.org/blog/the-linux-binfmt-subsystem.html/"/>
        <id>https://anadoxin.org/blog/the-linux-binfmt-subsystem.html/</id>
        
        <content type="html" xml:base="https://anadoxin.org/blog/the-linux-binfmt-subsystem.html/">&lt;p&gt;The binfmt subsystem is a special mechanism which allows the kernel to extend
its ability to recognize different executable binary formats. It&#x27;s invoked by
the kernel when the user wants to execute a file with the executable (+x) flag,
and its purpose is to help the kernel to understand the binary structure of
chosen file. This structure is crucial in determining which segments are
responsible for holding the program code and program data. Only by knowing such
information it is possible to interpret in a proper (and deterministic) way.&lt;&#x2F;p&gt;
&lt;!--break--&gt;
&lt;h2 id=&quot;some-history&quot;&gt;Some history&lt;&#x2F;h2&gt;
&lt;p&gt;On UNIX systems, the executable file format went through a quite big evolution,
similar to what the Windows file formats did. On UNIX&#x27;es, one of the oldest form
of executable formats was the a.out file, which was replaced by more functional
and user-friendly COFF format, which was — in turn — replaced by the ELF format.
ELF got its name from Executable and Linkable Format, or — in a different time
span — Extensible Linking Format, and it rules the executable format kingdom
until this very day.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, the variety of executable formats can be seen in more visible
colors when you start to consider the fact, that ELF structure is slightly
different on x86 and amd64 architectures. The problem is that the system needs
to support backward compatibility issues when running the software; thus it
needs to support both old formats, and new ones, to be regarded as usable. This
is where the binfmt subsystem comes in; it&#x27;s an easy way to allow the kernel to
choose which binary interpreter is the proper one for chosen executable file.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h2&gt;
&lt;p&gt;The file execution process begins in the &lt;code&gt;exec&lt;&#x2F;code&gt; function, implemented in your
local libc library. Every function from the &lt;code&gt;exec&lt;&#x2F;code&gt; family at some point will
enter the &lt;code&gt;execve()&lt;&#x2F;code&gt; function. It&#x27;s realized using the 0x80 interrupt (or by
sysenter instruction, or sometimes syscall), which is a standard way of
implementing a system service. The 0x80 interrupt, along with a number 11 in the
command register (more on this later) lets you switch the user-mode execution
context in favor of the kernel-mode execution context (ring 0). The interrupt,
when the command argument number is 11, is realized in the &lt;code&gt;sys_execve()&lt;&#x2F;code&gt; function
in the kernel, which resides inside &lt;code&gt;arch&#x2F;x86&#x2F;kernel&#x2F;process.c&lt;&#x2F;code&gt; file. So, to sum
it up: the code flow, after calling the &lt;code&gt;execve()&lt;&#x2F;code&gt; function inside libc, during
invocation of interrupt 0x80, goes through a “gate” living inside the IDT, which
tells the processor to start allowing more privileged instructions than standard
ring 3 ones (along with a bunch of other information), and jumps to the
&lt;code&gt;sys_execve()&lt;&#x2F;code&gt; function in the kernel (also, for completion: if the int 80h
instruction is implemented by sysenter or syscall instructions, the IDT part of
this transition is replaced by a read of special MSR registers allowing the
relocation of code flow pointer into the acquired address). The &lt;code&gt;sys_execve()&lt;&#x2F;code&gt;
function does the boring job of copying the arguments from ring 3 address space
into current ring 0 space, and invokes another function: &lt;code&gt;do_execve()&lt;&#x2F;code&gt;. This one
is just a temporary place for us, not doing anything of importance
related to our subject. The crucial part is the invocation of
&lt;code&gt;do_execve_common()&lt;&#x2F;code&gt;, which actually is doing something important, and interesting
;).&lt;&#x2F;p&gt;
&lt;p&gt;More or less, this function is designed to verify the security context of the
process, and to make sure that only the few selected handles will be inherited
by the new process, which at this point is yet to be created. It initializes the
memory management structures, which is of most importance for us. To
successfully perform this task, it invokes the &lt;code&gt;search_binary_handler()&lt;&#x2F;code&gt; function,
which tries to find a proper binary file interpreter, which knows how to walk
through the structure of our executable file.&lt;&#x2F;p&gt;
&lt;p&gt;In the kernel, every binary interpreter is implemented in its own source file,
like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fs&#x2F;binfmt_aout.c,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fs&#x2F;binfmt_elf.c,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fs&#x2F;binfmt_script.c,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;etc.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Every interpreter sticks to a few important rules, which allow them to live
inside the kernel ecosystem. One of the most important ones is to invoke the
&lt;code&gt;register_binfmt()&lt;&#x2F;code&gt; function, which notifies the kernel about the existence of the
interpreter. The function will pass the &lt;code&gt;linux_binfmt&lt;&#x2F;code&gt; structure, which contains
the &lt;code&gt;load_binary&lt;&#x2F;code&gt; field containing the pointer to a callback which gets invoked by
the kernel when it wants to match the interpreter with a specified binary file.
If the file structure is not what the interpreter understands (like trying to
use the ELF interpreter with a PE executable), it returns the &lt;code&gt;-ENOEXEC&lt;&#x2F;code&gt; error, to
notify the binfmt subsystem about a bad match. Then, the kernel will try another
interpreter from its pool of interpreters, until a final failure (no
interpreters match), or a success.&lt;&#x2F;p&gt;
&lt;p&gt;In other words: each built-in interpreter will issue a &lt;code&gt;load_binary&lt;&#x2F;code&gt; structure to
the kernel, to register itself in the kernel pool of interpreters. Interpreters
which live inside the Loadable Kernel Modules will also do the same stuff; it
means that the kernel constantly maintains a special table of interpreters (the
pool), and uses it to find an interpreter suitable for current task. I thought
it would be a nice idea to be able to peek though this table, to know what
executable interpreters are allowed by my current operating system ;)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-loadable-kernel-module-lkm&quot;&gt;The Loadable Kernel Module (LKM)&lt;&#x2F;h2&gt;
&lt;p&gt;Before we dive into creation of our LKM, let&#x27;s think of what the module should
do. The draft plan has been already created, but we need to dig some details to
know what structure fields are important for us and need reading, to get the
information we need. For this purpose it would be a good idea to quickly go
through the &lt;code&gt;search_binary_handler()&lt;&#x2F;code&gt;, which could be named as a core of binfmt
subsystem.&lt;&#x2F;p&gt;
&lt;p&gt;The function starts with a for loop after a block of sanity checks. The loop
uses the &lt;code&gt;list_for_each_entry&lt;&#x2F;code&gt; macro, which is a standard (for the kernel) method
of iterating over a double-linked list. The first argument (&lt;code&gt;fmt&lt;&#x2F;code&gt;) is the
iterator; this is a variable which points to a new row of data — it&#x27;s valid in
the whole scope inside the for expression, but not afterwards. The second
argument, &lt;code&gt;&amp;amp; formats&lt;&#x2F;code&gt;, is a pointer to the list we want to iterate on. Third
argument is a result of some peculiarities of the C language and the
&lt;code&gt;container_of&lt;&#x2F;code&gt; macro, and it&#x27;s a way of adjusting the compiler to properly cast
the type of the value in a type-safe fashion, to which the iterator points to.
More or less -- it&#x27;s not important at the moment, right now it&#x27;s just a “glue
code” for us. The important thing is that this for loop iterates over the
formats array, and allows the code inside its scope to access the member
objects, which are of the &lt;code&gt;linux_binfmt&lt;&#x2F;code&gt; type. Every iteration reads the
&lt;code&gt;load_binary&lt;&#x2F;code&gt; field, which is a pointer to a callback, invokes it, and checks the
return value. So, in other words, &lt;code&gt;formats&lt;&#x2F;code&gt; table is a table which holds
information about all the currently registered binary file interpreters. By
dumping the contents of this table we can get the list of binary formats that
are possible to be invoked on our system.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s write a LKM, which — after &lt;code&gt;insmod&lt;&#x2F;code&gt;&#x27;ing — will find its way into the formats
array and dump its contents to the user, but in a form, which would be
understandable by her without any addidional postprocessing, so it could be
possible to only use &lt;code&gt;cat&lt;&#x2F;code&gt; utility to read the contents of the file.
Unfortunately, there is a slight problem with that; the module can&#x27;t simply
display something on the screen. Such user interaction level is beyond the
abstraction level imposed by the module subsystem. The exchange of information
between the LKM and the user is done in a different way; best thing is to use a
combination of ring 3 application and ring 0 module. A normal ring 3 application
will send a question to the module, which the module will process, rendering the
answer to a simple flat byte buffer, which will in turn be sent to the
application as a response. Then the application will be able to display the
buffer on the screen by using &lt;code&gt;printf()&lt;&#x2F;code&gt;, a message box, or similar, whatever
method is needed by the user. The question sending part could be resolved by
using the &lt;code&gt;procfs&lt;&#x2F;code&gt; subsystem, which is a standard Linux way of sending information
between ring 3 and ring 0 in a full-duplex fashion. We will get into that
shortly, but for now it&#x27;ll suffice to say that it&#x27;s based on all of those
&lt;code&gt;&#x2F;proc&lt;&#x2F;code&gt; files, which could be read by simple tools like &lt;code&gt;cat&lt;&#x2F;code&gt;. These strings, which you
can observe while &lt;code&gt;cat&lt;&#x2F;code&gt;&#x27;ing one of the files from &lt;code&gt;&#x2F;proc&lt;&#x2F;code&gt;, are generated inside the
kernel, sent through the standard I&#x2F;O mechanisms to ring 3 application, to be
returned by standard I&#x2F;O functions like &lt;code&gt;read()&lt;&#x2F;code&gt;, and finally displayed on the
screen.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Notabene&lt;&#x2F;em&gt;, there is a shortcut we can use, when we want to quickly send some
information from the LKM to the user. It&#x27;s name is &lt;code&gt;printk&lt;&#x2F;code&gt; and it&#x27;s very similar
to standard printf. Two important details which you should note is that it
normally only works on the first physical console (&lt;code&gt;ctrl+alt+f1&lt;&#x2F;code&gt;; though this can
be configured later), and for it to work, you must first activate it by echo&#x27;ing
&lt;code&gt;9 9 9 9&lt;&#x2F;code&gt; to &lt;code&gt;&#x2F;proc&#x2F;sys&#x2F;kernel&#x2F;printk&lt;&#x2F;code&gt;. These numbers control the printk logs and
they specify the log levels, which kernel has to pass into the console output.
Log levels higher than the ones specified in this control file are ignored and
passed to &lt;code&gt;&#x2F;dev&#x2F;null&lt;&#x2F;code&gt; instead of the console (well, not exactly to &lt;code&gt;&#x2F;dev&#x2F;null&lt;&#x2F;code&gt;, but
I think you get the idea). Sometimes, by using daemons like &lt;code&gt;klogd&lt;&#x2F;code&gt;, the content
of &lt;code&gt;printk&lt;&#x2F;code&gt;&#x27;s buffer is stored inside system log files, like &lt;code&gt;&#x2F;var&#x2F;log&#x2F;kern.log&lt;&#x2F;code&gt;, so
you can also check if that&#x27;s the case for your system. Working or not, this
metod is valid only for communication between ring 0 and the developer, and you
shouldn&#x27;t use it on production code. You can peek into my other post, the &lt;a href=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;the-linux-binfmt-subsystem.html&#x2F;pci-device-enumeration-using-ports-0xcf8&quot;&gt;Device Enumeration on PCI bus&lt;&#x2F;a&gt;,
to see how &lt;code&gt;printk&lt;&#x2F;code&gt; can be used. It&#x27;s small and uncomplicated, so
it shouldn&#x27;t generate any further questions on &lt;em&gt;this subject&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;OK, so here&#x27;s the plan.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Create the module skeleton, which is compiled into the binary module file,
accepted by the insmod utility,&lt;&#x2F;li&gt;
&lt;li&gt;Find our way into the tables array, and interpret its contents,&lt;&#x2F;li&gt;
&lt;li&gt;Create our special &#x2F;proc entry, which will be used to exchange information
between ring 0 and ring 3.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Here&#x27;s a short demonstration, which is more friendly to the eye than naked text,
and catches the point of what we are to do:&lt;&#x2F;p&gt;
&lt;div &gt;
    &lt;iframe
        width=&quot;640&quot;
        height=&quot;360&quot;
        frameborder=&quot;0&quot;
        allow=&quot;picture-in-picture&quot;
        src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;L8cuRZjX52A&quot;
        webkitallowfullscreen
        mozallowfullscreen
        allowfullscreen&gt;
    &lt;&#x2F;iframe&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Before I venture to the second point, I suggest to take a closer look
to the third one. The characteristic traits of the &lt;code&gt;&#x2F;proc&lt;&#x2F;code&gt; filesystem handling can
influence the method which we will use to read the &lt;code&gt;formats&lt;&#x2F;code&gt; array. Not as much to
completely change the approach, but different enough to be worthy for a
dedicated description ;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-proc-filesystem&quot;&gt;The &#x2F;proc filesystem&lt;&#x2F;h2&gt;
&lt;p&gt;Some time ago I already wrote some stuff about this subject, along with some
information about process dumping on Linux systems in ring 3 (unfortunately,
this blog post is available only in Polish language, at this moment at least).
We&#x27;re going to take a look at the similar picture of &#x2F;proc filesystem interface,
but this time we&#x27;ll do it from ring 0 perspective.&lt;&#x2F;p&gt;
&lt;p&gt;A driver that wishes to create a new file in the &lt;code&gt;&#x2F;proc&lt;&#x2F;code&gt; directory has to call the
&lt;code&gt;create_proc_entry&lt;&#x2F;code&gt; function. It takes three arguments: the name of the file we
wish to create, the access rights to the file (encoded in a standard notation,
666 for &lt;code&gt;rwxrwxrwx&lt;&#x2F;code&gt;, 755 for &lt;code&gt;rwxr-xr-x&lt;&#x2F;code&gt;), and the pointer to the parent directory
in the &#x2F;proc filesystem. Last argument is only used when we want to create a
file in a subdirectory in &lt;code&gt;&#x2F;proc&lt;&#x2F;code&gt;; if we don&#x27;t plan on having any subdirectories,
it&#x27;s safe to just pass &lt;code&gt;NULL&lt;&#x2F;code&gt; to the third argument. Our example will not use any
directories, so we will use the function like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;proc_kformats = create_proc_entry(“kformats”, 755, NULL);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The global variable named &lt;code&gt;proc_kformats&lt;&#x2F;code&gt;, which is of type &lt;code&gt;proc_dir_entry&lt;&#x2F;code&gt;, will
contain a pointer to a new file descriptor, or &lt;code&gt;NULL&lt;&#x2F;code&gt;, if there will be some
problem with file creation (make sure you propely handle the fauly logic, f.e.
by returning &lt;code&gt;-EFAULT&lt;&#x2F;code&gt;). Before the system will actualy “show” the file to the
user, you will still need to provide some more information. The kernel will need
a list of callback functions, which are executed in case of a specific event
being triggered in the system. These callbacks should handle the &lt;code&gt;open()&lt;&#x2F;code&gt;, &lt;code&gt;read()&lt;&#x2F;code&gt;,
&lt;code&gt;lseek()&lt;&#x2F;code&gt;, and &lt;code&gt;close()&lt;&#x2F;code&gt; functions.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s an example. Standard use case for the &lt;code&gt;cat&lt;&#x2F;code&gt; command can look like the
following: first, after executing a &lt;code&gt;cat &#x2F;proc&#x2F;kformats&lt;&#x2F;code&gt; command, the
&lt;code&gt;&#x2F;proc&#x2F;kformats&lt;&#x2F;code&gt; file is being opened by the &lt;code&gt;open()&lt;&#x2F;code&gt; function, which is implemented
in your system libc. Then, the current read pointer is being set, just as by
invoking the &lt;code&gt;lseek()&lt;&#x2F;code&gt; function. Then the &lt;code&gt;cat&lt;&#x2F;code&gt; command reads the file by using the
&lt;code&gt;read()&lt;&#x2F;code&gt; function until it hits the end of file. After breaking the read loop, it
closes the file with the &lt;code&gt;close()&lt;&#x2F;code&gt; function. This is of course a very simplified
description of what the cat program does, but is accurate enough for our
example. So, by matching the callback list inside the LKM and the list of
actions which are going to be executed by &lt;code&gt;cat&lt;&#x2F;code&gt;, you can instruct the kernel that
if it gets an &lt;code&gt;open()&lt;&#x2F;code&gt; request on our file, it should invoke the
&lt;code&gt;my_driver_proc_file_open()&lt;&#x2F;code&gt; function from our LKM&#x27;s adress space. This function
should, of course, implement an “opening” logic for our file. When &lt;code&gt;cat&lt;&#x2F;code&gt; invokes
&lt;code&gt;lseek()&lt;&#x2F;code&gt;, the kernel will use &lt;code&gt;my_driver_proc_file_lseek()&lt;&#x2F;code&gt; function from our LKM,
which should implement a logic to set the offset from the input data source to a
specified value (only if our data source supports such operation).&lt;&#x2F;p&gt;
&lt;p&gt;The “list of actions”, “list of callbacks” is a variable of &lt;code&gt;file_operations&lt;&#x2F;code&gt;
type, and its definition can look like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;static struct&lt;&#x2F;span&gt;&lt;span&gt; file_operations kformats_file_ops &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .owner &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; THIS_MODULE,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .open &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; kformats_open,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .read &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; kformats_read,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .llseek &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; kformats_lseek,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .release &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; kformats_release&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Make sure to remember that if you don&#x27;t “bind” the file descriptor (which is a
structure, and it&#x27;s what the &lt;code&gt;create_proc_entry()&lt;&#x2F;code&gt; function returned) to the
&lt;code&gt;kformats_file_ops&lt;&#x2F;code&gt;, no callback from this structure will be invoked. The
“binding” part is very easy, and you can do it by taking the &lt;code&gt;kformats_file_ops&lt;&#x2F;code&gt;
address, and putting it into &lt;code&gt;proc_fops&lt;&#x2F;code&gt; field to the structure returned by
&lt;code&gt;create_proc_entry()&lt;&#x2F;code&gt;. After this operation the kernel will know how to route the
I&#x2F;O request from the &lt;code&gt;&#x2F;proc&#x2F;kformats&lt;&#x2F;code&gt; file into your module, then into your
structure, and finally into your callback handler. You can resort to the source
code to see how it&#x27;s done in the practice.&lt;&#x2F;p&gt;
&lt;p&gt;This approach could be described as a poor man&#x27;s object oriented programming,
and it&#x27;s very popular across the whole kernel — mostly because it suits the
purpose very well. The &lt;code&gt;file_operations&lt;&#x2F;code&gt; structure, as well as many others, use a
constant convention of function assignment to structure fields. This means that
the fields are becoming callbacks, ready to be invoked in different places in
the code. Object oriented purists will probably scream and attack us by saying
that of course that&#x27;s not a real object oriented programming, but we can simply
ignore them, because everyone who expects object orientation from the C language
should be treated like that :).&lt;&#x2F;p&gt;
&lt;p&gt;The main problem which everyone faces when implementing the &lt;code&gt;read()&lt;&#x2F;code&gt; function is
the need to manually manage data buffers, which are to hold our data. In other
words, when we have a structure, which we&#x27;d like to copy to memory accessible by
ring 3 application, we can&#x27;t simply take the pointer to the beginning of the
structure and copy &lt;code&gt;sizeof(structure)&lt;&#x2F;code&gt; bytes from it. That&#x27;s because when
implementing the &lt;code&gt;read()&lt;&#x2F;code&gt; function we are told (by the kernel) which part of the
structure needs to be copied, and how much bytes we&#x27;re allowed to copy.
Sometimes kernel tells us to copy the whole structure in one run, sometimes we
have to split it on two parts, sometimes copy it in chunks of 1 byte — it
depends on the arguments we&#x27;ll get from the kernel. Every call to &lt;code&gt;read()&lt;&#x2F;code&gt; should
increment an internal (also implemented by our code) counter which points to the
actual position (“cursor”) in our data stream. When you consider functions like
&lt;code&gt;lseek()&lt;&#x2F;code&gt;, or &lt;code&gt;ftell()&lt;&#x2F;code&gt;, you&#x27;ll probably be able to figure that they operate on this
cursor position: first one sets the cursor to a specified value, and the second
one returns the current value of it. Maybe all of this could be an easy thing to
do, but sometimes interaction with the hardware (which is what the LKM were
designed to do, afterall) can be tricky, also data cache&#x27;ing can increase the
complexity level of the problem.&lt;&#x2F;p&gt;
&lt;p&gt;This is why the kernel lends us a helping hand by providing us an abstraction
level for the basic I&#x2F;O functions. The level is implemented slightly higher than
the &lt;code&gt;file_operations&lt;&#x2F;code&gt; structure and it uses special callbacks, which are to be
used, instead of basic &lt;code&gt;read()&lt;&#x2F;code&gt;, &lt;code&gt;write()&lt;&#x2F;code&gt;, &lt;code&gt;llseek()&lt;&#x2F;code&gt; and &lt;code&gt;close()&lt;&#x2F;code&gt;. This mechanism
uses a different set of functions which are somewhat similar when it comes to
execution, but conceptually they operate on lines, instead of bytes, like the
basic mechanism. For the sake of stimulating your imagination, you can imagine
yourself the &lt;code&gt;putc()&lt;&#x2F;code&gt; function, which writes 1 character to the screen, and
&lt;code&gt;printf()&lt;&#x2F;code&gt; function, which is of course more advanced. &lt;code&gt;printf()&lt;&#x2F;code&gt; eventually will
call &lt;code&gt;putc()&lt;&#x2F;code&gt; at some point, but the truth is, we don&#x27;t need to know how
&lt;code&gt;putc()&lt;&#x2F;code&gt;
works; we can print stuff on the screen by just knowing how &lt;code&gt;printf()&lt;&#x2F;code&gt; works. Same
thing here; The  &lt;code&gt;seq&lt;&#x2F;code&gt; subsystem of which I&#x27;m writing about operates on lines, so
we only need to know how produce the next line in the stream. When we&#x27;ll feed
this line into the &lt;code&gt;seq&lt;&#x2F;code&gt;&#x27;s “flow”, it will implement a proper &lt;code&gt;read()&lt;&#x2F;code&gt; callback so
the kernel will get the whole line, without needing to take care of buffering
issues, cursors, pointers, etc. That&#x27;s plain convinience! Of course, at some
point it&#x27;ll be very useful to know the internals of the standard I&#x2F;O mechanism,
but if you want, you can postpone learning of it (the shorter the better).&lt;&#x2F;p&gt;
&lt;p&gt;So, our declaration will change a little:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;static struct&lt;&#x2F;span&gt;&lt;span&gt; file_operations kformats_file_ops &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .owner &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; THIS_MODULE,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .open &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; kformats_open,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .read &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; seq_read,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .llseek &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; seq_lseek,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .release &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; seq_release&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can probably see very well that the &lt;code&gt;read()&lt;&#x2F;code&gt; function is implemented in
&lt;code&gt;seq_read()&lt;&#x2F;code&gt; (which is already done and you don&#x27;t need to change it), &lt;code&gt;llseek()&lt;&#x2F;code&gt; is
replaced by &lt;code&gt;seq_lseek()&lt;&#x2F;code&gt;, same thing with &lt;code&gt;release()&lt;&#x2F;code&gt; and &lt;code&gt;seq_release()&lt;&#x2F;code&gt;. So, the
only function which needs to be implemented in this structure, is the body of
open() function. And even then, it&#x27;s very likely that lots of your &lt;code&gt;open()&lt;&#x2F;code&gt;
functions will look like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;static int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; kformats_open&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; inode &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;inode&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; file &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;file&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; seq_open&lt;&#x2F;span&gt;&lt;span&gt;(file,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; kformats_seq_ops);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It&#x27;s not complicated, but it&#x27;s important. Its only role is invocation of
&lt;code&gt;seq_open()&lt;&#x2F;code&gt; function, which registers this file reading session with the &lt;code&gt;seq&lt;&#x2F;code&gt;
subsystem. The subsystem needs to be initialized with the &lt;code&gt;seq_operations&lt;&#x2F;code&gt;
structure, which is passed into the second argument of &lt;code&gt;seq_open()&lt;&#x2F;code&gt;. Here&#x27;s what
this structure looks like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;static struct&lt;&#x2F;span&gt;&lt;span&gt; seq_operations kformats_seq_ops &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .start &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; seq_file_start,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .next &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; seq_file_next,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .stop &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; seq_file_stop,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .show &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; seq_file_show&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So what is the purpose of those fields? The &lt;code&gt;.start&lt;&#x2F;code&gt; callback gets called when &lt;code&gt;seq&lt;&#x2F;code&gt;
wants to start the streaming process. &lt;code&gt;.next&lt;&#x2F;code&gt; will be used to notify your code that
it needs to prepare itself to be able to provide another line of data. &lt;code&gt;.show&lt;&#x2F;code&gt; will
be called when the line will be rendered, and finally &lt;code&gt;.stop&lt;&#x2F;code&gt; will be a
notification for finishing the streaming process. So, in practice, in &lt;code&gt;.open&lt;&#x2F;code&gt; you
initialize your structures, in &lt;code&gt;.next&lt;&#x2F;code&gt; you position the “cursor” on to the next
item to read, in &lt;code&gt;.show&lt;&#x2F;code&gt; you read the data from the “cursor&#x27;s” position, and in
&lt;code&gt;.finish&lt;&#x2F;code&gt; you deinitialize everything that you did in the initialization step.
Every callback function in one of the arguments will contain the pointer to the
file descriptor you&#x27;re going to manipulate on, so implementations of these
functions will have to use that information instead of any global variables you
might have. Every call to these functions will have to be reentrant, or at least
thread-aware, so best practice would be to not use any of the shared data at
all. Unfortunately, in our case, we have to use the reference to shared data
(the &lt;code&gt;formats&lt;&#x2F;code&gt; array), so we will have to implement a proper locking code to make
our implementations thread-aware, and the invocation of our module safe both to
the system and to our module.&lt;&#x2F;p&gt;
&lt;p&gt;Now it&#x27;s finally the time to think about the process of getting into the &lt;code&gt;formats&lt;&#x2F;code&gt;
array, from the &lt;code&gt;seq&lt;&#x2F;code&gt;&#x27;s interface point of view. The &lt;code&gt;.start&lt;&#x2F;code&gt; callback will
initialize the access to the structure, by locking the mutexes guarding the
array (so the structure won&#x27;t change when we&#x27;re walking over it). The &lt;code&gt;.next&lt;&#x2F;code&gt;
callback will increase the “cursor” (“iterator”) forward by 1 position. &lt;code&gt;.show&lt;&#x2F;code&gt;
callback will read the element pointed to by the cursor (iterator), and will
convert binary data into the human-readable form (by using printf(), for
example). Finally, the &lt;code&gt;.stop&lt;&#x2F;code&gt; callback will have to unlock the guard mutex,
because if we&#x27;d leave it locked, it would hang the whole system up (the
&lt;code&gt;formats&lt;&#x2F;code&gt;
array is used every time a process is created, after all). Before we enter the
realm of implementation, I&#x27;d like to write about two more things, which are
important in our case. The first one is a method which we&#x27;ll use to find the
&lt;code&gt;formats&lt;&#x2F;code&gt; table in the memory labirynth, and the second one is how we actually
handle that mutex part, that is: how to fit into the multithreaded system, and
find out the exact moment when we&#x27;re able to saftely read the structure, without
risking invalid memory access exceptions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;dynamic-symbol-localization-kallsyms&quot;&gt;Dynamic symbol localization — kallsyms&lt;&#x2F;h2&gt;
&lt;p&gt;The kernel must have this subsystem compiled in. Luckily, it seems that most
systems fulfill this prerequisite. It&#x27;s very easy to check if that&#x27;s the case
for your system; it&#x27;s enough to check if the &lt;code&gt;&#x2F;proc&#x2F;kallsyms&lt;&#x2F;code&gt; file exists.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(2:1003)$ ls -la &#x2F;proc&#x2F;kallsyms&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-r--r--r-- 1 root root 0 09-13 21:58 &#x2F;proc&#x2F;kallsyms&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The contents of this file is the same thing (or should be) as the contents of
the &#x2F;boot&#x2F;System.map file, and it basically is a list of variable names,
function names and their current addresses in the memory. This addresses are
generated automatically by the compiler when compiling the kernel, and their
value depends on many things, but I think it&#x27;s safe to assume that it&#x27;s mostly
the optimization level which the compiler is using, and the number of things
compiled in the kernel. These settings are so peculiar that it&#x27;s safe to assume,
that the kernel on every installation is different. To be more specific, most
differences occur between distributions, not between versions of one distro, but
still there can be many versions of the kernel in different time span (thanks to
automatic updates) in the boundary of one distribution. Of course, when we take
into account distributions such as Gentoo, Sabayon, or similar, or distros on
which the user compiles her own kernel, the “different kernel on every
installation” assumption makes sense. This means we simply can&#x27;t just write down
the memory location of our variable, which we&#x27;ll find on our system. If we&#x27;d do
that then the module would probably work only on our system, and that&#x27;s only
before automatic updates will replace the kernel to newer version. We need a
more robust solution for looking up variables in the memory.&lt;&#x2F;p&gt;
&lt;p&gt;The subsystem which will be perfect for our case is called kallsyms. The main
function which we&#x27;re going to use is named &lt;code&gt;kallsyms_lookup_name()&lt;&#x2F;code&gt; and it&#x27;s
designed to do lookup the variable name, which we&#x27;ll supply in its first
argument. The return value is the current address of this symbol in current
memory, so it&#x27;s possible to dereference it, and just use it (most of the time,
not counting dynamic allocations). So, using kallsyms, looking up the address of
the formats array is trivial:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	g_formats_list &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; list_head &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; kallsyms_lookup_name&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;formats&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The code above will save the address of the &lt;code&gt;formats&lt;&#x2F;code&gt; table in the
&lt;code&gt;g_formats_list&lt;&#x2F;code&gt;
variable, which is declared in our module. The type of &lt;code&gt;g_formats_list&lt;&#x2F;code&gt; is a
standard double-linked list, used in various places across the whole kernel. You
can look that information up on Google, because it goes slightly our of scope of
the subject of this post.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;synchronization&quot;&gt;Synchronization&lt;&#x2F;h2&gt;
&lt;p&gt;Writing a kernel module is similar to writing a plugin to a bigger system (not
necessarily an operating system). Many aspects of the runtime environment in
which our module is working is based on an event-driven architecture and there
can be many reasons why our code will execute. Sometimes it will be called from
one thread, sometimes from the other thread, and sometimes it&#x27;ll be called from
two (or more) threads at the same time. On a single-CPU machine, the first
instance will be interrupted and put into sleep, so other instance can jump into
its place and begin execution for a specified amount of time. Then, the control
is again reclaimed by the first module, during the time when the second one
sleeps. On a multi-CPU machine, many copies of one function can run at the same
time — that copies will operate on the same data sets. It&#x27;s best to assume that
an unlimited number of threads, laid out on an unlimited set of CPUs is running
at the same time. So, where does that bring us?&lt;&#x2F;p&gt;
&lt;p&gt;To the same point that any other multithreaded application brings us. So, we
simply use mutexes and spinlocks (along with some variations, like: mutex
locking the code only on write requests), atomic counters (atomic_t — atomic
means “not divisable”, or “uniform”, not explosive!), but there are also more
sophisticated methods of synchronization, like RCU — read-copy update (where the
write request copies the data into another memory location, updating the
reference pointers where its needed — this way the reading thread is not locked
and can operate on the old data set, and the new thread and every otherthread
which will access the data set after this point, will operate on new data set).&lt;&#x2F;p&gt;
&lt;p&gt;Check &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.ibm.com&#x2F;developerworks&#x2F;linux&#x2F;library&#x2F;l-linux-synchronization&#x2F;index.html&quot;&gt;this article&lt;&#x2F;a&gt; if you want to learn something about kernel mechanisms for
synchronization. This article is slightly out of date, because the Big Kernel
Lock it describes is no longer in the kernel, but still it&#x27;s a valuable piece of
information for everyone who wants to learn about the subject.&lt;&#x2F;p&gt;
&lt;p&gt;So where&#x27;s the common point of this and our project? Well, the point is: it&#x27;s
very important. Consider this example: you take the address of the formats
table. Then you start to iterate on every element of this table, printing the
address of the element on the screen. Very little can go wrong with this easy
example, right? Nope, wrong, if you include another thread in this scenario.
When during the first thread&#x27;s iteration phase, the second thread will try to
remove an item, it can lead us into a situation where the first thread accesses
the memory that has just been freed by the second thread. Of course, the first
thread, when dereferencing the iterator, won&#x27;t detect any errors, because the
memory still exists and it&#x27;s valid; but even one instruction later, the first
thread&#x27;s code can be preempted, or interrupted, and the second thread will jump
in, where it&#x27;ll do its removal logic. Then, the first thread will resume its
execution, and this is where we are at: the first thread, in the block of code
that assumes the memory is valid (because it already did the checks), but the
memory is not valid. Kernel panic ahead! So where&#x27;s the problem and how to fix
it? The problem is that the second thread did the removal stuff, but it didn&#x27;t
knew that somebody else is reading the same data set at the same time. So, it
would be good to have some kind of mechanism, so that threads can broadcast the
information about the data set they&#x27;re reading or writing to, so other threads
can wait until this access is finished. After waiting, they broadcast the read,
or modification signal themselves, so other threads won&#x27;t start to read what
they intend to modify. After removing, or writing their part, they broadcast the
signal that the data set is free to process again. This is called locking, or
blocking a data set (structure, or anything that&#x27;s a variable).&lt;&#x2F;p&gt;
&lt;p&gt;So, if you&#x27;d like to acquire a data set with exclusive access, you can use, for
example, a Mutex. The broadcasting part is called locking a structure, or
entering a critical section. Many structures, and variables, in the kernel have
their respective mutex objects, which are used to lock the structure, so it&#x27;s
accessed only by one thread at a time. It&#x27;s no different in our case of the
&lt;code&gt;formats&lt;&#x2F;code&gt; table; the locking object for this table is a read write lock (which is
a mutex) in the form of the &lt;code&gt;binfmt_lock&lt;&#x2F;code&gt; variable. I suggest you look it up in
the kenrel sources to know where it&#x27;s located and learn the pattern for this,
because — as I already wrote — it&#x27;s popular among other kernel structures. To
add things up, before you do anything with the &lt;code&gt;formats&lt;&#x2F;code&gt; table, you need to lock
the &lt;code&gt;binfmt_lock&lt;&#x2F;code&gt; object according to your action. When you&#x27;re finished with
whatever you do with the &lt;code&gt;formats&lt;&#x2F;code&gt; table, just unlock the mutex, so other threads
can process this table, and you&#x27;re done. I&#x27;ve also told you that many kernel
structures have their own respective locking objects; but it&#x27;s up to you to find
them. There&#x27;s no standard “slot” in the structure you can put the
synchronization objects in; you have to read the source code and figure out
which ones to use, by yourself.&lt;&#x2F;p&gt;
&lt;p&gt;The address of the &lt;code&gt;binfmt_lock&lt;&#x2F;code&gt; mutex can be acquired in the same way you acquire
the &lt;code&gt;formats&lt;&#x2F;code&gt; table&#x27;s address:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;g_binfmt_lock &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;rwlock_t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; kallsyms_lookup_name&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;binfmt_lock&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can read-lock this mutex by using the &lt;code&gt;read_lock()&lt;&#x2F;code&gt; function, and read-unlock
it by using &lt;code&gt;read_unlock()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;I think I&#x27;ve managed to describe most of the theoretical aspects of the approach
I&#x27;ll be using in the code: you should know what the binfmt system is, and what
we are to do. You also should know the place that holds the data which is of
most importance for us and you should know how to access that data. Last section
described the method of reading the data, and the first one described how to
present the data to the user.&lt;&#x2F;p&gt;
&lt;p&gt;So, let&#x27;s go into some details.&lt;&#x2F;p&gt;
&lt;p&gt;Getting the address of the &lt;code&gt;formats&lt;&#x2F;code&gt; table and its synchronization mutex,
&lt;code&gt;binfmt_lock&lt;&#x2F;code&gt;. If the kallsyms subsystem is not compiled in the kernel, the
module won&#x27;t allow itself to be loaded. The insmod program will return an
error. But in the optimistic case (which is the majority), here&#x27;s the code.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;static int&lt;&#x2F;span&gt;&lt;span&gt; __init &lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;kefdump_init&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    g_formats_list &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; list_head &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; kallsyms_lookup_name&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;formats&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    g_binfmt_lock &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;rwlock_t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; kallsyms_lookup_name&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;binfmt_lock&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt; g_formats_list &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;|| !&lt;&#x2F;span&gt;&lt;span&gt; g_binfmt_lock)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;            return -&lt;&#x2F;span&gt;&lt;span&gt;EFAULT;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The module creates the virtual file inside a virtual file system &lt;code&gt;&#x2F;proc&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;proc_kformats &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; create_proc_entry&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;kformats&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 755&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; NULL&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt; proc_kformats) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    printk&lt;&#x2F;span&gt;&lt;span&gt;(KERN_ERR &lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;can&amp;#39;t create_proc_entry&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    return -&lt;&#x2F;span&gt;&lt;span&gt;ENOMEM;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The action list of the &lt;code&gt;kformats&lt;&#x2F;code&gt; file is defined by the &lt;code&gt;kformats_file_ops&lt;&#x2F;code&gt;
structure. This structure uses a convention imposed by the &lt;code&gt;seq&lt;&#x2F;code&gt; subsystem, so the
&lt;code&gt;read&lt;&#x2F;code&gt;, &lt;code&gt;llseek&lt;&#x2F;code&gt; and &lt;code&gt;release&lt;&#x2F;code&gt; fields are pointing to the &lt;code&gt;seq&lt;&#x2F;code&gt; domain.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;proc_kformats&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;proc_fops &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;= &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; kformats_file_ops;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Initialization is complete, the module is loaded.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;	TRACE0&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;kformats installed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, the user needs to read the &lt;code&gt;&#x2F;proc&#x2F;kformats&lt;&#x2F;code&gt; file, so we can analyze further
what the module does. The &lt;code&gt;cat &#x2F;proc&#x2F;kformats&lt;&#x2F;code&gt; command should do the trick. The
&lt;code&gt;cat&lt;&#x2F;code&gt; command first opens the file (by using the &lt;code&gt;fopen()&lt;&#x2F;code&gt; function, for example,
which in turn uses the &lt;code&gt;open()&lt;&#x2F;code&gt; syscall), then it reads the data from it, and
closes the file in the epilogue of its execution (the &lt;code&gt;close()&lt;&#x2F;code&gt; syscall). Let&#x27;s
consult that with our action structure:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;static struct&lt;&#x2F;span&gt;&lt;span&gt; file_operations kformats_file_ops &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .owner &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; THIS_MODULE,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .open &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; kformats_open,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .read &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; seq_read,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .llseek &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; seq_lseek,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .release &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; seq_release&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So, first the &lt;code&gt;kformats_open&lt;&#x2F;code&gt; will be invoked, because &lt;code&gt;cat&lt;&#x2F;code&gt; opens the file.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;static int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; kformats_open&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; inode &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;inode&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; file &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;file&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; seq_open&lt;&#x2F;span&gt;&lt;span&gt;(file,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; kformats_seq_ops);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We initialize the &lt;code&gt;seq&lt;&#x2F;code&gt; subsystem here. This is the control structure for &lt;code&gt;seq&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;static struct&lt;&#x2F;span&gt;&lt;span&gt; seq_operations kformats_seq_ops &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .start &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; seq_file_start,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .next &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; seq_file_next,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .stop &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; seq_file_stop,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .show &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; seq_file_show&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;What it means is that the control of serving the &lt;code&gt;&#x2F;proc&#x2F;kformats&lt;&#x2F;code&gt; file is given to
the &lt;code&gt;seq&lt;&#x2F;code&gt; filesystem, so we stick to its rules; then we only need to implement a
simple loop-like construct to be able to fully implement serving of the file
contents. &lt;code&gt;.start&lt;&#x2F;code&gt; is the beginning of the loop, and it&#x27;s the initialization of
data structure we want to print. In our case we will lock the &lt;code&gt;binfmt_lock&lt;&#x2F;code&gt; here,
so no other thread will be able to write-access the &lt;code&gt;formats&lt;&#x2F;code&gt; table, not even the
operating system itself (remember, by writing the kernel module, you&#x27;re writing
the operating system itself). Read-access will be allowed for anyone. That&#x27;s
the advantage of using the rwlock instead of a conventional lock.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;static void *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;seq_file_start&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; seq_file &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;s&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; loff_t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;pos&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    TRACE0&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;lock&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    read_lock&lt;&#x2F;span&gt;&lt;span&gt;(g_binfmt_lock);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; pos &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; g_formats_list-&amp;gt;next;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;!-- _*__ --&gt;
&lt;p&gt;The function will return a pointer to the first item in the table. By the way;
if the user will request read from f.e. a middle of the file, the function will
return zero. This is because our module doesn&#x27;t support starting reading from
any other element that is not the first element.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;cat&lt;&#x2F;code&gt; program, after opening the file, will start reading from it. This will
result in triggering the &lt;code&gt;next&lt;&#x2F;code&gt; and &lt;code&gt;show&lt;&#x2F;code&gt; actions, all the way down until the next
function will return &lt;code&gt;NULL&lt;&#x2F;code&gt; — signalling the end of the data. This is our
implementation of the &lt;code&gt;next&lt;&#x2F;code&gt; function. Its job is to increment the data iterator
together with fetching the pointer to the &lt;code&gt;next&lt;&#x2F;code&gt; element, and here&#x27;s how it does
this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;static void *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;seq_file_next&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; seq_file &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;s&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; void *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;iterator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; loff_t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;pos&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;	struct&lt;&#x2F;span&gt;&lt;span&gt; list_head &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;next &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; NULL&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; pos)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	next &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; ((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; list_head &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;) iterator)-&amp;gt;next;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span&gt;(next &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span&gt; g_formats_list) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span&gt; next;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; NULL&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;formats&lt;&#x2F;code&gt; table uses the standard double-linked list structure. The
characteristic part of this table is that the last element is linked with the
first one; so by incrementing the iterator, while standing on the last element,
we&#x27;ll end up on the first element again. This is the reason for our expression
above: if the &lt;code&gt;next&lt;&#x2F;code&gt; var is the same as &lt;code&gt;g_formats_list&lt;&#x2F;code&gt;, it means that we&#x27;re on the
beginning again, so we already got past the end of the table, so we can break
the loop. We return &lt;code&gt;NULL&lt;&#x2F;code&gt; to signal that we got the end of the data. When the
kernel will see the &lt;code&gt;NULL&lt;&#x2F;code&gt; value, it won&#x27;t call the next function anymore.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;static int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; seq_file_show&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span&gt; seq_file &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;s&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; void *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt;iterator&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span&gt; linux_binfmt &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;fmt &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; NULL&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    char&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E36209;&quot;&gt; namebuf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;512&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fmt &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; container_of&lt;&#x2F;span&gt;&lt;span&gt;(iterator,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span&gt; linux_binfmt, lh);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    sprint_symbol&lt;&#x2F;span&gt;&lt;span&gt;(namebuf, (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;unsigned long&lt;&#x2F;span&gt;&lt;span&gt;) fmt-&amp;gt;load_binary);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    seq_printf&lt;&#x2F;span&gt;&lt;span&gt;(s,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;%s\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, namebuf);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So, nothing complicated here. The &lt;code&gt;sprint_symbol()&lt;&#x2F;code&gt; is a function that is a
logical mirror of the &lt;code&gt;kallsyms_lookup_name&lt;&#x2F;code&gt; — that is, it&#x27;s designed to perform
the opposite — it will convert the address of the symbol to the symbol name. Of
course, the address must be valid in order to do it. The &lt;code&gt;container_of&lt;&#x2F;code&gt; macro is a
method of iterator dereferencing, and I encourage you to read about it.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s about it. In case you&#x27;d like to share your thoughts or point out any
errors, feel free to use the “comment” link below.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;anadoxin.org&#x2F;blog&#x2F;the-linux-binfmt-subsystem.html&#x2F;adx-kefdump.tar.bz2&quot;&gt;Source Codes&lt;&#x2F;a&gt; (5kb)&lt;&#x2F;p&gt;
&lt;!--
vim:set ft=markdown:
--&gt;
</content>
        
    </entry>
</feed>
