I'm planning to do a mass-bug-filing against packages that mention dbus-x11 in their dependencies, or dbus-launch in their code, asking maintainers to adjust their dependencies to make dbus-x11 optional. My goal is that users can install the major desktop tasks in stretch (GNOME, KDE, etc.) with either one of dbus-user-session or dbus-x11, defaulting to dbus-user-session for new installations.
I'm deliberately not doing a dd-list yet because there's an open question about the order of preference, but the affected source packages are basically <https://codesearch.debian.net/search?q=dbus-%28x11|launch%29> (minus some false positives that just mention dbus-launch or dbus-x11 without any technical effect). I'll re-post this with a dd-list when there's something like consensus. The tl;dr version: * I think we should default to dbus-user-session for stretch on Linux. * dbus-launch (dbus-x11) without dbus-user-session should continue to be supported, but should be a non-default configuration on Linux. * On kFreeBSD and Hurd, dbus-launch is still the best we can do. * Regression tests should use dbus-run-session, not dbus-launch, on all kernels. * Fallback plan: make it possible for early adopters to use dbus-user-session instead of dbus-launch, but keep dbus-launch the default for new installs even on Linux, and reconsider for stretch+1. Background: ways you might get a session bus ============================================ As of current stable, the correct way to start a "production" D-Bus session in Debian was for /etc/X11/Xsession.d to invoke dbus-launch(1). This would result in a session bus (dbus-daemon) per X11 display, and is set up by the dbus-x11 package. The dbus-daemon terminates when the X11 display does. dbus 1.10 in testing/unstable introduces a new way for systemd users to get a D-Bus session bus per uid (the *user bus*), shared between all parallel logins whether they are X11, Wayland, Mir, text or non-interactive. This is not 100% compatible with traditional practice, particularly if you have two or more parallel X11 logins with the same uid (GNOME's gdm won't do that, but some other display managers do), which is why it is "opt-in". In Debian, this is not done by default, but can be activated by installing the dbus-user-session package. In this case the dbus-daemon terminates when "systemd --user" does, which is when the uid responsible for this dbus-daemon ends their last parallel login session. Some desktop environment core components, such as GNOME's gnome-session, will automatically start a session bus per login session using dbus-launch if there is not already one available. I believe GNOME on Wayland currently relies on this mechanism if dbus-user-session is not installed. This session bus terminates when the X11 display does (in the case of GNOME on Wayland, the X11 display is XWayland, and terminates when gnome-shell does). Similarly, regression tests sometimes start a fake X11 display (Xvfb) and run dbus-launch scoped to that X11 display. Another possible way to get a session bus is to run dbus-run-session(1), or run dbus-daemon directly (typically using its --print-address option). This is frequently done by regression tests. In this case, a dbus-daemon started by dbus-run-session is terminated when dbus-run-session's child process terminates, and a directly-run dbus-daemon must be killed by the test script at the appropriate time. Finally, if you start a program that uses D-Bus with no session bus running, and you have an X11 display, the D-Bus library (typically libdbus or GLib's GDBus) will attempt "X11 autolaunching": the program forks and execs dbus-launch in a special "autolaunching" mode, and the various dbus-launch processes that were started in this way attempt to acquire a hidden X11 resource. Whichever dbus-launch process happens to get there first forks and execs the dbus-daemon for this X11 session, then continues to run to supervise it; the other dbus-launch processes just report its address back to their parents and then terminate. This mode is discouraged, and not particularly reliable: it has a tendency to start the dbus-daemon in a somewhat precarious situation, as a child of some random GUI app with arbitrary environment variables, resource limits, std{in,out,err} fds and so on. Autolaunching can also get used if you run a graphical program under su/sudo with access to your X11 display (but seriously, don't do that). X11 autolaunching may have been important 10 years ago, when people installed D-Bus into distributions that didn't otherwise integrate it, and used it to run individual GNOME or KDE apps inside a fvwm session or something. However, in 2016 and in a well-integrated distribution like Debian, I would be inclined to treat any use of X11 autolaunching as a bug. Why should we prefer dbus-user-session? ======================================= * If a GUI login session is running (for example you are logged-in to a GUI environment but the screen is locked), your cron jobs and ssh sessions on the same machine can share the desktop's user-services like dconf, Telepathy, fd.o Secrets (gnome-keyring/KWallet). * It's a good fit for the design of user-services like dconf. They can take a bus name on the user bus and be confident that this acts as a mutex locking out other instances of the user service on the same machine, avoiding "last write wins" data loss for all configurations where $HOME is not shared between machines. * It's also very suitable for taking per-user daemons that use D-Bus and would more usually be run in a desktop login session (for example exporting media to a UPnP receiver like a PS3 using Rygel, with Tracker for indexing) and turning them into pseudo-system-services running as a dedicated user: a systemd service with PAMName= and User= is enough to get a systemd --user instance and an accompanying dbus-daemon for that user, which is enough to support services like Rygel. * dbus-daemon is not a fully-featured service manager: it can start session services on-demand, but it doesn't support resource limiting, disabling services, non-D-Bus services and so on (nor should it - that isn't in its scope, and it doesn't have enough regular contributors to be a good idea to expand its scope to something like that). The user bus can use a fully-featured service manager, "systemd --user", for service activation. * As a systemd user service, the user bus is started in a known context with predictable/controllable environment variables, resource limits and so on. * The traditional D-Bus session bus uses abstract Unix sockets on Linux, to ensure automatic cleanup even if the dbus-daemon is terminated uncleanly. These sockets are always shared with container-based sandboxes, unless you start a new network namespace (which unshares all abstract Unix sockets, and also IP networking). The user bus uses a single filesystem-backed socket per uid, which is easy to inspect with standard Unix tools ("everything is a file") and is more container-friendly: it is not shared by default, but can be shared with a simple bind mount. * dbus-launch is fairly horrible code, complicated by the historical need for it to support X11 autolaunching, so the D-Bus maintainers would like to move it out of the critical path and minimize its use. Why should dbus-user-session be optional? ========================================= * The current implementation[1] requires systemd and systemd-logind. This is not portable to non-Linux kernels, and upsets some Linux users. [This is not set in stone; there's no reason why someone couldn't write a PAM module that started a user bus, but the people doing the work so far are happy with systemd taking responsibility for that.] * Some desktop environments (including many configurations of "build your own desktop environment from pieces") do support multiple parallel X11 sessions per uid per machine. In these setups, the user bus breaks the expectations of software that assumes it can run once per X11 session, in parallel, and take the same bus name on the session bus corresponding to each X11 session (for example gnome-settings-daemon has this behaviour). [It is possible to use a bus name like com.example.MyService.X0 if you want a bus name per X11 display, although this would require coordinated code changes in the service and its consumers.] * The per-X11-session bus would disconnect all background services (or at least those that happen to use D-Bus) on each X11 logout; well-behaved D-Bus services respond to this by terminating. The user bus isn't normally terminated until all processes in the login session have exited, which can result in background services lingering (more precisely, if a login-session process lingers, then the dbus-daemon and other non-GUI processes will too). [If this is important to you, for example in a university computer lab, consider using systemd-logind's KillUserProcesses option, which is the default upstream since 230 but not in Debian; it's more thorough, and does not depend on the implementation detail of whether processes happen to use D-Bus for IPC.] Recommendations for libraries ============================= This recommendation applies to library implementations of D-Bus such as libdbus, GLib's GDBus, systemd's sd-bus, dbus-sharp and dbus-java, when connecting to the standard session bus. If the environment variable DBUS_SESSION_BUS_ADDRESS is set, libraries must use that address when asked to connect to the session bus. If DBUS_SESSION_BUS_ADDRESS is unset, but XDG_RUNTIME_DIR is set, and $XDG_RUNTIME_DIR/bus is a socket owned by the correct uid, libraries must use that socket (for instance by substituting the XDG_RUNTIME_DIR, escaped as a D-Bus address component, into "unix:path=${escaped_xdg_runtime_dir}/bus"). If neither of those is available, libraries may use X11 autolaunching (the "autolaunch:" pseudo-transport) like libdbus and GDBus do, or they may simply fail the connection attempt like sd-bus does. I anticipate that for stretch+1 or stretch+2, we might want to recommend that libraries like libdbus and GDBus should disable X11 autolaunching, and fail to connect in the circumstances where they would have used it. Recommendations for desktop sessions ==================================== This recommendation applies to desktop sessions like GNOME, and desktop sessions' core infrastructure like gnome-session. Desktop sessions that make use of D-Bus should depend on Depends: dbus-user-session | dbus-x11 (Open question: do we want this way round, or dbus-x11 | d-u-s?) If a desktop environment works better with the "user bus" (I anticipate that GNOME might do this in stretch or stretch+1), it may indicate that with: Depends: dbus-user-session | dbus-x11 Recommends: dbus-user-session If a desktop environment strictly depends on the "user bus", it may instead depend on Depends: dbus-user-session but maintainers should note that this eliminates sysadmins' ability to choose between the "login session bus" and "user bus" models without patching the software, is an indirect systemd dependency, and in particular is uninstallable on non-Linux kernels. Desktop sessions may execute dbus-launch if they are started with DBUS_SESSION_BUS_ADDRESS absent from the environment, and either XDG_RUNTIME_DIR unset, or a socket named $XDG_RUNTIME_DIR/bus not existing or owned by the wrong uid. This code path should not normally be necessary (and should not be run in practice) in Debian X11 sessions or with dbus-user-session installed, but might be useful in Wayland sessions with dbus-user-session not installed, or as part of upstream support for distributions with less careful X11 integration than Debian. Recommendations for regression tests ==================================== This recommendation applies to packages that run tests at build time, packages with autopkgtests, and all similar situations. Regression tests should either use dbus-run-session, which is an "adverb" command like sudo or fakeroot: Depends: dbus (>= 1.8) dbus-run-session -- make check or if finer control is needed, start a dbus-daemon the hard way, something like this: Depends: dbus #!/bin/sh dbus-daemon --session --fork --print-address=4 --print-pid=5 4>address.tmp 5>pid.tmp trap 'kill $(cat pid.tmp); rm -f address.tmp pid.tmp' EXIT export DBUS_SESSION_BUS_ADDRESS="$(cat address.tmp)" make check If a special configuration file for the dbus-daemon is required, use dbus-run-session --config=special.conf -- make check or dbus-daemon --config=special.conf --fork --print-address=4 ... Recommendations for other software that relies on D-Bus ======================================================= This recommendation applies to ordinary apps that rely on having a session bus but are not a core part of a desktop environment, such as the Empathy real-time communications client. These packages should rely on the distribution and the desktop environment cooperating to ensure that a session bus is provided. A hard requirement for a session bus should be indicated like this: Depends: dbus-user-session | dbus-x11 (Open question: do we prefer d-x | d-u-s?) A softer requirement can be indicated by a similar Recommends or Suggests. These packages should not attempt to run dbus-launch or dbus-daemon, except as a side-effect of using a library that supports X11 autolaunching - it is not their responsibility. Discussion/contact ================== Please discuss this proposed MBF on debian-devel or by contacting d...@packages.debian.org. [1] Please contact the D-Bus upstream mailing list if you are interested in implementing a user bus without systemd. You will need something resembling pam_xdg_support (which is what Ubuntu used before they switched to systemd) to provide the XDG_RUNTIME_DIR, plus some way to start the actual dbus-daemon, probably from the same or a different PAM module. Note that since Ubuntu does not use or maintain pam_xdg_support any more, you will likely need to become its new upstream maintainer, or fork it as a basis for your new PAM module. Regards, S