D-Bus User Bus

Lennart Poettering mzqohf at 0pointer.de
Fri May 14 11:56:44 PDT 2010


On Fri, 14.05.10 10:01, Scott James Remnant (scott at ubuntu.com) wrote:

> Since we're all in proposals mood, I'd like to forward the suggestion of
> allowing D-Bus to support a User Bus, as well as the existing Session
> and System buses.

I am against this. While I probably want to come to the same goal as you
do, I am suggesting going things differently -- and without a seperate
user bus.

I used to be a proponent of a user bus, and in fact I still have a
checkout lying around here which implements most of the logic of a user
bus. However I have since changed my position on this and am now more
siding with Colin who wants to redefine the current session bus a little
so that it becomes a more of a user bus. A seperate per-session bus is
unnecessary if we have a per-user bus; instead of seperating services of
session via the notion of multiple busses, we should seperate them via a
display id of some kind in the bus names (if necessary at all). 

(Much of what follows is inspired by
http://developer.apple.com/mac/library/technotes/tn2005/tn2083.html
which makes a very good read and I only can recommend everybody to read
it from top to bottom. Of course this covers MacOS X but many of the
thoughts pointed out there apply to our Linux/D-Bus system too. Simply
think "D-Bus" whenever you read "Mach" -- Mach is the original
microkernel MacOSX is based on which has mostly lost its relevance
except for being at the core of the IPC model.)

A few observations to start with:

- the current separation between sessions of the same user has no value
  for security purposes: security sandboxing on the lower levels happens
  along user id priviliges, not session ids. If a user cannot trust
  himself, who can he trust?

- the current separation between sessions of the same user has little
  value for the lifecycle of sessions: UI programs terminate anyway when
  X goes down, from inside libX11; and even if that limitation might be
  removed one day, the default for UI programs should and will continue
  to be that they quit when the display server goes away. And anyway,
  gnome-session should determine the life-cycle of the UI services, not
  dbus.

- generally, we should emphasize sharing of data between sessions of the
  the same user. Ideally we'd even allow copy/paste between them.

- it is a simple fact that currently only a handful of gnome
  applications can safely be run on multiple graphical logins in
  parallel. IIRC kde's session manager actviely disallows multiple logins
  by the same user. Instead of miserably failing Gnome apps should be
  more explicit about this, too i guess.

- I think it is love's labor's lost to ask each and every UI program to
  be fixed for multiple parallel logins of the same user. Teaching every
  programmer about the intricacies just doesn't scale. Also the value
  is minimal, since all desktop environments support virtual desktops
  anyway.

- adding another bus complicates an already complex system where new
  users already have a hard time grasping the difference between the
  system and session bus

- we already have a lot of services on the bus and moving them from one
  to the other won't be fun, if we want to keep compat.

- the current scheme does not care at all for SSH logins (or console
  logins). Nor does it cover cronjobs.

- currently, all out busses are per-machine, however the specs leave
  that open, so that busses could in theory be redfined to be
  network transparent in case of NFS $HOME or networked X11
  displays. However I think this is not
  realistic to achieve. Again, many programs are simply not up for it,
  for example because they assume that the FS namespace is identical on
  the bus client and the bus server. That could often be fixed but this
  would also have a perfomance cost since it would require data to be
  shoved through the bus itself. Then, there's the fw issue: there's no
  sane way to even get a TCP connection reliably established between the
  machine running the X11 display and the app. Finally, let's not forget
  that the emphasis of networked computing is more on VNC these days,
  less on X11.

So, putting this together here's what I'd do: change the definition of
the current session bus from "one is started for each X11 display
session and is bound to its lifetime" to "one is started for each user
from the time he first logs in to the last time he logs out, and all
this bound to the machine". The bus hence becomes ref counted by the
displays/ttys the user is logged in from. Logging in hence becomes an
act of adding a display/tty to the session, and logout removes a
display/tty from the session.

If we do this and otherwise keep client apps unmodified this of course
would mean that all those which pick a name on the bus could only be
started once per user. This I think is actually a good thing, because
the majority of apps probably already cannot be started more then once
by the same user, however instead of a clean error you get an unhelpful
disastrous failure later on. The s/session-bus/user-bus/g change would
simply make this fact explicit. Of course, some clients are safe to be
run more than once and it is desirable for them, and those should be
fixed to pick a per-display name on the bus. Example:

  org.gnome.Metacity.Display1  -- metacity on display #1
  org.gnome.Metacity.Display2  -- metacity on display #2
  org.mozilla.firefox          -- firefox as an example of an app that cannot be started on more than one display at a time
  org.gnome.dconfd             -- dconfd as an example of a per-user daemon offering its services to apps on all displays

A look on a possible process tree:

 |
 +-- dbus-daemon --session (for user lennart)  \
 |    |                                         }-- the per-user daemons
 |    +-- dconfd (bus activated)               /
 |
 +-- gdm             
 |    |
 |    +-- gnome-session (for user lennart)     \
 |         |                                    }-- the per-session daemons
 |         +-- metacity                         }
 |         +-- firefox                         /
 |
 +-- dbus-daemon --session for user keybuk     \
 |    |                                         }-- the per-user daemons
 |    +-- dconfd (bus activated)                }
 |    +-- keyring (dito)                       /
 |
 +-- sshd
      | 
      +-- /bin/sh (for user keybuk)             }-- the per-session daemons
 
One possible implementation for starting up this newly redefined
per-session daemon wouldd be to have a tiny dbus agent on the system bus
that dbus-launch talks to and is ref-counted by dbus-launch. Another one
(and which I'll eventually pursue) is that CK simply starts a systemd
unit for each user that logs in.

Also, this whole discussion should  be seen in front of the recent
discussions on xdg regarding a per-user machine-local socket dir. I'd
also vote for a simple per-user dir where those services which need
sockets place their sockets into. If they want to allow being started
once for each display they can take a socket file name that includes the
display id, much the same way as the bus name logic pointed out above.

We should forget about network transparency of the session bus and just
declare that it is per-machine and that people are sfae to assume that
clients and servers live in the same fs and pid namespace. If programs
from multiple machines run on the same display they get a seperate
machine-local bus, like they already do. Declaring this will gain us
more than we'd lose, I'd say.

Of course the redifinition of the session bus clogs the nomenclature a
bit: the dbus session bus will suddenly become a user bus, while the
"session" in gnome-session will retains its meaning as being something
bound to login on a specific display. That is unfortunate of course, but
I thin we could live with that.

As a display id for the bus and socket names we could simply use the
current XDG_SESSION_COOKIE, which is set by CK anyway. however, an
alternative would be to ask users to simply use $DISPLAY or `tty` (for
ssh/console agents).

So far my ideas. I think they make a lot more sense then introducing yet
another bus. A seperate per-user bus might be the straight-forward idea
when you first think about this, but I think redifining the current
session bus into this direction is in the end the better choice.

Lennart

-- 
Lennart Poettering                        Red Hat, Inc.
lennart [at] poettering [dot] net
http://0pointer.net/lennart/           GnuPG 0x1A015CC4


More information about the dbus mailing list