[systemd-devel] User sessions, session buses, user buses

Lennart Poettering mzqohf at 0pointer.de
Mon Feb 2 14:04:17 PST 2015


On Fri, 30.01.15 09:30, Simon McVittie (simon.mcvittie at collabora.co.uk) wrote:

> user-session
> ------------
> 
> I don't think there is a standard term for this so I'm making one up.
> The XDG_RUNTIME_DIR specification says that there is at most one
> XDG_RUNTIME_DIR per uid per machine, that it is created at the beginning
> of the user's first login session, and that it is removed at the end of
> a login session if no other login sessions remain for that uid.
> systemd-logind implements those semantics, and also runs a `systemd --user`
> for the lifetime of the user-session. Ubuntu previously used
> libpam-xdg-runtime to provide compatible semantics without systemd.
> The resulting situation looks something like this (assume all the
> sessions shown are under the same uid):
> 
>     --------\             ========\\
>     login   |             user-   ||
>     session |  --------\  session || <- overlapping login session c42
>     23      |  login   |          ||    shares the user-session with 23
>     --------/  session |          || <- 23 ends but c42 keeps u.-session
>                c42     |          ||    alive
>     --------\          |          || <- 57 begins, shares u.-sess.
>     login   |  --------/          || <- c42 ends, 57 keeps user-session
>     session |                     ||    alive
>     57      |                     ||
>     --------/             ========// no more l.sessions, u.-session ends
> 
>     --------\             ========\\ new l.session, u.-session starts
>     login   |             user-   ||
>     session |             session ||
>     ...     .             ...     ..
> 
> user-sessions do not have any meaningful identifier apart from their
> owner's uid (strictly speaking, the owner's "loginuid", i.e. the user
> who initially logged in, even if they su). They do not need another
> identifier, because by definition there is only one per uid at a
> time.

Small addition: these "super-sessions" are slightly modulated by the
"linger" boolean setting that logind manages per-user. If that boolean
is true the user's "super-session" stays alive from boot to shutdown.

> Digression: (at least some) users and developers don't want that
> ----------------------------------------------------------------

Adding in here: note that firefox and some other apps actually lock
thheir configuration directory, so that it effectively a singleton
program per-user anyway. One of the most important apps of the user is
hence per-use anyway, even if started in a per-session context.

>   "It's already been discussed multiple times on the list and
>   apparently a user bus is too confusing or not really useful unless
>   you make it a user bus shared across a network cluster. I don't
>   agree, and I think that the consequence of this stance will be a
>   proliferation of hacks like the one I just sketched out (not to
>   mention even grosser hacks like Ubuntu's ACPI scripts grepping the
>   environment of the user's processes in /proc to find their session
>   bus to tell their screensaver to lock)."

Not convinced that the ACPI thing is a good example. It's not a
confusion about session/user contexts, but more a confusion about
privileged code calling into unprvileged code, which should never
happen.

> This leaves the problem that, if you have chosen the
> user-session-centric model, current D-Bus doesn't actually work very
> well: we have dbus-launch and dbus-run-session for login-session-centric
> D-Bus, but if you want to make D-Bus user-session-centric, you need to
> resort to third-party user bus units like user-session-units, which
> float around Github and somehow never make it upstream. I'm now on my
> third unrelated work project that contains a copypaste of dbus.socket
> and dbus.service, and I'm sure my colleagues have others - this is not
> the flying car future I signed up for. So I would like to get this stuff
> upstream into dbus.git.
> 
> So that the people who are happy with the complexities of the current
> arrangement can remain happy, here is how I intend it to work:
> 
> * ./configure --disable-user-bus: you get a login-session-centric world
> * ./configure --enable-user-bus: you get a user-session-centric world
> * configure either way and selectively install/delete files: you can
>   either have a login-session-centric or user-session-centric world,
>   depending what you install. (This is so I can have dbus-user-bus and
>   dbus-x11 binary packages in Debian, where the answer to "do A or do
>   B?" is always "both!", without having to compile everything twice;
>   the GNOME metapackage could eventually depend on dbus-user-bus.)

So far our logic in systemd was to simply set the $DBUS_SESSION_BUS_ADDRESS
to the user bus address, to redirect all access to the session bus to
the user bus.

> Sadly, not all the issues have been resolved yet. The biggest is
> environment variables: on existing systems there is an expectation
> that environment variables set by *dm, PAM, or /etc/X11/Xsession.d
> (or the non-Debian equivalent) will be propagated into every process
> in the session. In a brief survey of about half the Xsession.d scripts
> in Debian, I identified these environment variables:
> 
> * PULSE_SERVER

Note that PA can actually derive the PA server address from the X11
server, hence this is not strictly necessary.

> * ESPEAKER
> * XDG_DATA_HOME, XDG_DATA_DIRS
> * each variable printed by locale(1)
> * VDPAU_DRIVER
> * GTK_IM_MODULE, QT_IM_MODULE, QT4_IM_MODULE, CLUTTER_IM_MODULE,
>   XMODIFIERS
> * GTK_MODULES
> 
> plus the obvious ones set by *dm, such as DISPLAY, or by PAM. Similarly,
> a user's ~/.xsession can set arbitrary variables - mine sets CCACHE_DIR,
> EDITOR, MPD_HOST and XDG_CONFIG_DIRS, among others.

At the hackfest Ryan suggested we should simply intrdouce a
~/.config/environment file or so, that is always sources in at the
beginning of each super-session. It wouldn't be a real shell script,
but only support the most basic environment assignments.

> The naive implementation would be to run a tool at the end of
> /etc/X11/Xsession.d that uploads all of these into `dbus-daemon
> --session` (if used) and into `systemd --user` (if used). However, not
> all environment variables set in such scripts are suitable for that use:
> notably, XDG_SESSION_ID from the login session should not be copied into
> activated processes that exist outside any login session.

Note that as a tool to make this easy for the case of $DISPLAY, we
added "systemctl --user import-environent DISPLAY" which uploads specific
client env vars into the systemd instance. In fact, Kay recently added
to systemd a script that installs $(sysconfdir)/X11/xinit/xinitrc.d/50-systemd-user.sh 
containing this

    #!/bin/sh
    systemctl --user import-environment DISPLAY XAUTHORITY

With this in place GNOME works pretty much flawlessly with kdbus and a
per-user bus.

> As a short-term solution, I'm tempted to write that tool, but make it
> only upload a whitelisted set of variables automatically, and say "if
> you install dbus-user-bus, you are expected to run this tool from your
> ~/.xsession if you need it".

I figure that tool already exists ;-)

Lennart

-- 
Lennart Poettering, Red Hat


More information about the dbus mailing list