[modular-debian] Replace dbus with per-service filesystems (was: Re: Humor With A Message: dbus)

  • From: Jude Nelson <judecn@xxxxxxxxx>
  • Date: Sat, 6 Dec 2014 03:36:02 -0500

Hi everyone,

(warning, wall of text)

I'm interested in helping to develop a more modular debian, built from
interchangeable, composable parts to facilitate creating a Universal OS.
To me, this includes ensuring that each component can be manipulated via a
well-defined, generic interfaces that allow us to re-use as much existing
infrastructure as possible to interact with it.

Recently, this blog post [0] got me thinking about the state of affairs
with regards to dbus-exposed services.  Given how filesystem-like dbus is,
why not simply design services to export a userspace filesystem in the
first place (taking a leaf out of Plan 9)?  I think doing so would promote
a more modular, composable userspace than what we have today with dbus,
since it would allow us to:
* bring to bear the whole ecosystem of existing and future file-oriented
tools to administrate services in a generic manner, instead of having to
rely on component-specific methods, protocols, and tools;
* avoid having to re-invent dbus-specific analogs of said ecosystem (such
as qdbus);
* avoid tying ourselves to the future of dbus--we're already tied to the
future of POSIX anyway; there's no need to increase this technical debt if
we can avoid it.

If my understanding of dbus is correct (someone please correct me if I'm
wrong), the key features it offers to applications include the following:
* signals and methods as first-class entities
* hierarchical organization:  processes aggregate related signals and
methods under common prefixes; two different processes A and B have their
own prefixes to avoid namespace collisions
* introspection:  process A can query the signals and methods exposed by
process B
* RPC-like IPC semantics:  process A can invoke methods in process B (both
synchronous and asynchronous operations are allowed)
* 1-to-N broadcast:  process A can send a signal to one or more listener
processes B1...BN.
* authentication:  processes A and B only interact once they prove to one
another that they each know a shared secret (which is shared out-of-band by
a mutually trusted party, like a session manager or an ancestor process).
* activation and lifecycle management:  process A can learn when process B
exposes or withdraws an API

But, if this is what dbus conventionally gets used for, then I think the
features offered by dbus could be addressed with a userspace filesystem as
* signals and methods:  represented by files, or well-defined directory
* hierarchical organization:  directory trees
* introspection:  opendir(), readdir(), stat(), getxattr(), listxattr()
* RPC-like semantics:  open(), read(), write(), close(); can be used to
emulate method invocations if need be (i.e. write arguments to a file; read
result from a file).
* 1-to-N broadcast:  combination of select()/poll() and read() (also:
inotify(), kqueue, etc.)
* authentication:  process's PID, effective UID/GID, access(), path
* activation and lifecycle management:  mount(), umount(), mount namespace
(/etc/mtab, /proc/mounts)

I'm convinced that per-service filesystems encourage modularity better than
dbus to the point that I've gone ahead and created a library, called fskit
[1], that makes it easy to embed them into services.  Unlike FUSE, fskit
handles all the bookkeeping required to maintain a POSIX-y directory
hierarchy, and lets the service programmer define WSGI-style routes to
handle I/O operations over sets of paths (a multi-threaded RAM filesystem
can be had in about 200 lines of C).  It's almost ready for a stable
release--it's only missing symlink and hard-link support at this point--but
I've already used it to create a special RAM filesystem, called runfs [2],
that automatically removes files once the process that created them dies
(i.e. no more stale PID files).  I use it every day to avoid polluting my
/tmp with files generated (but not cleaned up) by software I work on at

Before I dive off the deep end into doing something big like
re-implementing udev, I'm looking for a sanity check.  Is what I'm trying
to do a desirable, or even a sensible, approach towards encouraging a more
modular debian?  To be clear, it's not that I dislike dbus; it's that the
lack of generic interfaces between dbus components makes it difficult for
me to avoid tightly coupling multiple dbus services together.  I think this
can be avoided if services stuck to generic conventions for interacting
with the rest of the system (such as the POSIX filesystem API), since then
existing tools would not need to be designed around the services'
otherwise-arbitrary methods and their arbitrary side-effects.  I think
making it easy for services to expose functionality through the filesystem
is a big step in this direction.

Any thoughts or feedback welcome :)


[1] https://github.com/jcnelson/fskit
[2] https://github.com/jcnelson/runfs

On Thu, Dec 4, 2014 at 5:36 PM, Martinx - ジェームズ <thiagocmartinsc@xxxxxxxxx>

> On 4 December 2014 at 14:03, David L. Craig <dlc.usa@xxxxxxxxx> wrote:
> > Can we agree dbus is to be avoided?
> I'm using Linux since 1996 (Debian since Potato), never used dbus (on
> servers) in my entire life.
> I see no reason to start using now.
> Cheers!

Other related posts: