<?xml version="1.0" encoding="UTF-8" standalone="yes"?><oembed><version><![CDATA[1.0]]></version><provider_name><![CDATA[Software is Crap]]></provider_name><provider_url><![CDATA[https://davmac.wordpress.com]]></provider_url><author_name><![CDATA[davmac]]></author_name><author_url><![CDATA[https://davmac.wordpress.com/author/davmac/]]></author_url><title><![CDATA[D-Bus is completely&nbsp;unnecesary]]></title><type><![CDATA[link]]></type><html><![CDATA[<p>So for various reasons I&#8217;ve got to thinking about <a href="http://www.freedesktop.org/wiki/Software/dbus/">D-Bus</a>, the &#8220;system bus&#8221; that&#8217;s found its way into most (all?) Linux distributions and possibly some other OSes as well. I&#8217;m more and more coming to believe that D-Bus is too heavyweight a solution for the problems it was intended to solve &#8211; mostly because it requires a daemon, and because we don&#8217;t really the <em>bus</em> aspect (at least, not in the form in which it&#8217;s been implemented).</p>
<p>How did I come to this conclusion? Well, consider first that, in essence, D-Bus provides only the following functionality:</p>
<ul>
<li>Protocol (and associated library) for a simple RPC mechanism (you can call a method in a &#8220;remote&#8221; process, and receive a reply).</li>
<li>Basic security for this RPC. Basically the policy specification allows different between different users and groups, and whether the user is &#8220;at the console&#8221;.</li>
<li>Map service names to the processes that provide the service (for purposes of connecting to said service).</li>
<li>&#8220;Bus activation&#8221;, i.e. starting a process which provides a service when the given service is requested but is not currently being provided.</li>
</ul>
<p>That&#8217;s really all there is to it. The fact that these are the only functions of D-Bus is, in my view, a good thing; it fits with the mantra of &#8220;do one thing, and do it well&#8221;. However, the question is if D-Bus is actually needed <em>at all</em>. Consider the &#8220;traditional approach&#8221; where services each have their own unix-family socket and listen on that for client requests. How does that compare to the feature set of D-Bus? Well:</p>
<ul>
<li>Protocol is application specific (D-Bus wins)</li>
<li>Security configuration is also application specific (D-Bus wins)</li>
<li>Service is determined by socket path (about as good as D-Bus, since service names and socket paths are both pretty arbitrary)</li>
<li>No activation &#8211; server needs to be running before client connects (D-Bus wins)</li>
</ul>
<p>So, in general, D-Bus wins, right? But wait &#8211; there are a few things we haven&#8217;t considered.</p>
<p>Like libraries.</p>
<p>Yes, protocols for communication with server programs via a socket are generally application specific, but on the other hand, there is usually a library that implements that protocol, which takes some of that pain away. Of course these libraries are language-specific, so there is a duplication of effort required in adapting library interfaces to other programming languages, but there are tools like <a href="http://www.swig.org/">SWIG</a> which can assist here. Also, there&#8217;s the possibility that services could offer a standard protocol (similar to the D-Bus protocol, even) for communication over their respective sockets. It turns out there <a href="http://www.simple-is-better.org/rpc/">are</a> <a href="https://developers.google.com/protocol-buffers/">options</a> available which give some basic functionality; I&#8217;m sure that it wouldn&#8217;t be too hard to come up with (or find [<a href="http://qooxdoo.org/docs/general/rpc/jsonrpc_introspection">1</a>] [<a href="http://xmlrpc-c.sourceforge.net/introspection.html">2</a>]) something which offer basic introspection as well. Heck, you could even use the D-Bus protocol, just without the intermediary server!</p>
<p>How about security? Well, because sockets themselves can be assigned unix permissions, we actually get some of the D-Bus security for free. For any given service, I can easily restrict access to a single user or a single group, and if I wanted to I could use ACLs to give more fine-grained permissions. On the other hand, central configuration of security policy can be nice. But that could be implemented by a library, too. If only there was <a href="http://www.linux-pam.org/whatispam.html">some pre-existing library specifically for this purpose</a>&#8230; ok, so PAM isn&#8217;t really meant for fine-grained security either, since it breaks things down to the service level and not any further. But it wouldn&#8217;t be hard to come up with something better &#8211; something that allows fine-grained policy, with significantly greater flexibility than D-Bus offers.</p>
<p>As mentioned above, there&#8217;s pretty much no difference between choosing a service name and choosing a socket path, so I don&#8217;t need to say much about this. However, it would certainly be possible to have a more standard socket path location &#8211; /var/run/service/<em>name</em> or something similar.</p>
<p>That just leaves <em>activation</em> as the only issue. D-Bus can start a process to provide a requested service. But it happens that this can be done quite easily with plain unix sockets, too; it&#8217;s called &#8220;socket activation&#8221; in the SystemD world, and it&#8217;s supported by various other service managers as well (including my own still-in-alpha-infancy <a href="https://github.com/davmac314/dinit">Dinit</a>). You could even potentially have service handover (processes queuing to own the socket), just like D-Bus has, though I don&#8217;t know if any existing service managers can do this (and on the other hand, I&#8217;m not even convinced that it&#8217;s particularly valuable functionality).</p>
<p>So: replace the protocol and security with libraries (potentially even a single library for both), and use your service management/supervision system for activation. Why do we actually need the D-Bus daemon?</p>
<p>I have a vague idea that some library might spring into existence which implements an abstraction over the D-Bus API but using the ideas presented here (which, let&#8217;s face it, are astounding only in their simplicity) instead of communicating with a single central daemon. That is, connecting to a D-Bus service would just connect to the appropriate (some name-mangling required) socket within /var/run/service, and then speak the D-Bus protocol (or another similar protocol) to it. Likewise, requesting a service would instead attempt to listen on the corresponding socket &#8211; for unprivileged processes this might require assistance from a SUID helper program or perhaps the requisite functionality could be included in the service manager. Unfortunately I&#8217;ve got too many other projects on my plate right now, but maybe one day&#8230;</p>
<p>&nbsp;</p>
]]></html></oembed>