After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 693668 - RFC: optionally run the greeter session with systemd --user
RFC: optionally run the greeter session with systemd --user
Status: RESOLVED OBSOLETE
Product: gdm
Classification: Core
Component: general
unspecified
Other Linux
: Normal enhancement
: ---
Assigned To: GDM maintainers
GDM maintainers
Depends on:
Blocks:
 
 
Reported: 2013-02-12 18:12 UTC by Simon McVittie
Modified: 2018-02-12 15:00 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Add a --with-run-dir which sets the default for everything in [/var]/run (2.95 KB, patch)
2013-02-12 18:15 UTC, Simon McVittie
committed Details | Review
Get rid of some unused variables (2.59 KB, patch)
2013-02-12 18:16 UTC, Simon McVittie
committed Details | Review
GdmLaunchEnvironment: allow a session bus address to be passed in (5.87 KB, patch)
2013-02-12 18:17 UTC, Simon McVittie
committed Details | Review
GdmSimpleSlave: give each greeter a unique XDG runtime directory (2.91 KB, patch)
2013-02-12 18:26 UTC, Simon McVittie
none Details | Review
Optionally use systemd to start greeter sessions (10.22 KB, patch)
2013-02-12 18:36 UTC, Simon McVittie
none Details | Review
Work around systemd --user not knowing how to escape D-Bus addresses (2.04 KB, patch)
2013-02-12 18:37 UTC, Simon McVittie
none Details | Review
proof-of-concept: rely on user@.service for our session buses (3.26 KB, patch)
2013-02-22 17:41 UTC, Simon McVittie
none Details | Review
Don't wrap dbus-launch around gnome-session, only around gdm-simple-chooser (2.96 KB, patch)
2013-02-22 18:52 UTC, Simon McVittie
none Details | Review

Description Simon McVittie 2013-02-12 18:12:56 UTC
I've been investigating how/whether the gdm greeter (and other special-purpose sessions like gnome-initial-setup) can be made to use systemd --user as their session manager. This allows session services used by the greeter (particularly D-Bus session services) to be started in parallel and managed by the user systemd instance. As a side benefit, it also allows dbus-launch to be avoided entirely.

It might even be possible to bypass gnome-session entirely, but for now, gnome-session is just another "child" of the systemd --user process, so it looks something like this:

gdm-simple-slave (root)
\- systemd --user (gdm)
   \- dbus-daemon
   \- gnome-session
      \- gnome-shell
      \- gnome-settings-daemon
   \- pulseaudio
   \- dconf-service
   \- etc.
Comment 1 Simon McVittie 2013-02-12 18:15:44 UTC
Created attachment 235801 [details] [review]
Add a --with-run-dir which sets the default for  everything in [/var]/run

---

The same as I attached to Bug #692733; I realise it was rejected there. I'll see whether I can work out what's going on with `make distcheck` on that bug...
Comment 2 Simon McVittie 2013-02-12 18:16:28 UTC
Created attachment 235802 [details] [review]
Get rid of some unused variables

---

Cleanup. If it compiles, this can be applied whenever, I think?
Comment 3 Simon McVittie 2013-02-12 18:17:18 UTC
Created attachment 235803 [details] [review]
GdmLaunchEnvironment: allow a session bus address to  be passed in

If we're given an explicit session bus address, don't wrap the command
in a redundant dbus-launch.
Comment 4 Simon McVittie 2013-02-12 18:26:15 UTC
Created attachment 235807 [details] [review]
GdmSimpleSlave: give each greeter a unique XDG runtime  directory

Normally, if a user has multiple login sessions, they're meant to share
a runtime directory. For the greeter, we actively don't want that: we
want each X11 display to be its own little session, so it can have its
own Orca and so on.

Create a base directory for them all (which happens to correspond to
the default GDM_SCREENSHOT_DIR at the moment) in the main daemon, then create
each display's runtime directory in the corresponding launch environment.

---

I realise now I attach this that the commit message is wrong, but I don't expect to be able to merge this stuff as-is, so, attaching it for comment anyway.

I was briefly using directories like /var/run/gdm/greeter/:0, but have ended up with /var/run/gdm/greeter-:0 instead - I had some trouble with .../greeter getting deleted for some reason.

This use of XDG_RUNTIME_DIR contradicts its specification, but I think that might indicate that the specification isn't considering system users: I think we do need the greeter to be able to exist in more than one parallel session, each with its own D-Bus session, even if we don't support more than one parallel D-Bus session for "real users".

One possible alternative would be to have some way in which gdm could make the dbus.socket user service (currently in e.g. <https://github.com/sofar/user-session-units>, but it should clearly go upstream to dbus when agreed upon) listen on a socket other than $XDG_RUNTIME_DIR/dbus/user_bus_socket - then we could have multiple D-Bus sessions in one $XDG_RUNTIME_DIR?
Comment 5 Simon McVittie 2013-02-12 18:36:46 UTC
Created attachment 235808 [details] [review]
Optionally use systemd to start greeter sessions

For the moment we assume that each greeter session ID
(gdm-shell, and eventually gdm-fallback and gnome-initial-setup)
corresponds to a systemd target, e.g. gdm-shell.target.

For now we just run one systemd job, gnome-session-gdm-shell.service,
which runs the gdm-shell gnome-session session. Later, we could replace
that service with the individual bits of gdm-shell.

This assumes dbus.service and dbus.socket from user-session-units;
they should ideally go upstream, to dbus.

---

A production-quality version of this would have to also provide gdm-fallback.target, or perhaps use a common gdm-session.target and pass the preferred session in as an environment variable or something?

Having done this, symlinking other services' units into user/gdm-shell.target.wants can be used to preload those services: on my test system I've done this for at-spi-dbus-bus, dconf and pulseaudio (with appropriate systemd <-> D-Bus hookup for at-spi-dbus-bus and dconf).
Comment 6 Simon McVittie 2013-02-12 18:37:14 UTC
Created attachment 235809 [details] [review]
Work around systemd --user not knowing how to escape  D-Bus addresses

Workaround for https://bugs.freedesktop.org/show_bug.cgi?id=60499
Comment 7 Simon McVittie 2013-02-12 19:25:17 UTC
Review of attachment 235809 [details] [review]:

::: daemon/gdm-simple-slave.c
@@ +1035,3 @@
+         * This code isn't completely right - in principle the display name
+         * could contain _ which would lead to aliasing - but it'll do. */
+        escaped_display_name = g_uri_escape_string (display_name, "", FALSE);

This would be better with Bug #693673 fixed (or we could copy the same function into gdm to do the escaping properly).
Comment 8 Simon McVittie 2013-02-20 13:34:17 UTC
(In reply to comment #4)
> Normally, if a user has multiple login sessions, they're meant to share
> a runtime directory. For the greeter, we actively don't want that: we
> want each X11 display to be its own little session, so it can have its
> own Orca and so on.

This will need discussion with systemd upstream: it clashes with how pam_systemd currently works (creating an XDG_RUNTIME_DIR for each login1.User, which is any overlapping series of login1.Sessions with the same uid) and how upstream want it to operate in future (running a systemd --user and a dbus-daemon --session for each login1.User, whereas here we want one of those per login1.Session).

The answer might be an "isolated_session" parameter to pam_systemd, or something, which either suppresses the systemd/dbus-daemon, or makes an XDG_RUNTIME_DIR/systemd/dbus-daemon combination per login1.Session?
Comment 9 Simon McVittie 2013-02-20 13:35:07 UTC
See also the thread I started about login sessions vs. user sessions, currently cross-posted to the systemd and gdm lists (let me know if the gdm list should be removed).
Comment 10 Ray Strode [halfline] 2013-02-20 16:42:44 UTC
(pushing some of the prerequisite patches for now)
Comment 11 Simon McVittie 2013-02-22 17:41:46 UTC
Created attachment 237203 [details] [review]
proof-of-concept: rely on user@.service for our session  buses

This requires unmerged patches in systemd.

---

This is certainly not suitable for merging - it assumes "the world is systemd" and requires my unmerged patches from systemd bug <https://bugs.freedesktop.org/show_bug.cgi?id=61129>, together with a similar patch for dbus for full functionality - but it does work, in the way that systemd upstream intend (one big session per uid).

It will break things that assume one session D-Bus per X11 display - that's unavoidable, given the constraint of the "user bus" design that systemd upstream want. Please contribute to the thread starting at <http://lists.freedesktop.org/archives/systemd-devel/2013-February/009119.html> if you have strong opinions on that.

The gnome-session part can be made redundant by making gnome-session prefer to use $XDG_RUNTIME_DIR/dbus/user_bus_socket (if that socket exists) rather than running dbus-launch, or by having pam_systemd put DBUS_SESSION_BUS_ADDRESS in the environment.

The greeter part is somewhat harder: at the moment, gdm decides whether to wrap the greeter in dbus-launch based on very incomplete information.

One way to fix it would be to move the decision on whether to wrap the greeter in dbus-launch until a later point, after the GdmSessionWorker has run PAM modules. At that point, it can know what the XDG_RUNTIME_DIR is going to be, and also know that if pam_systemd is going to set up dbus/user_bus_socket, then it has already done so; so it can see whether there is a socket, and set DBUS_SESSION_BUS_ADDRESS "at the last moment".

Another way to fix it, which I'll try next, would be to not use dbus-launch at all. All the sessions that gdm is willing to execute are gnome-session, which ensures that it has D-Bus - so we can just rely on that, I think?
Comment 12 Simon McVittie 2013-02-22 18:52:23 UTC
Created attachment 237210 [details] [review]
Don't wrap dbus-launch around gnome-session, only around  gdm-simple-chooser

gnome-session already knows how to re-exec itself with a gnome-session
if necessary, and also (with a patch I've just written) how to pick up
the user bus from systemd instead. Don't second-guess that, it just
results in extra buses.

---

This is an alternative to Attachment #237203 [details]; Attachment #235803 [details] would need to be reverted first. (Sorry, it's taken me a while to piece together how the intended design works...)

The "patch I've just written" is Bug #694472.
Comment 13 Ray Strode [halfline] 2013-02-25 20:26:33 UTC
maybe pam_systemd shoud set DBUS_SESSION_BUS_ADDRESS
Comment 14 Ray Strode [halfline] 2013-02-25 20:28:23 UTC
*should.

What i mean is, if dbus-daemon is going to be socket activated, then setting DBUS_SESSION_BUS_ADDRESS to the socket location should always work, even in the absense of systemd --user right? So we should just unconditionally set it if using systemd.  We can set it in gdm based on sd_is_booted() or we can set it in pam_systemd.  The latter seems more conceptually clean to me.
Comment 15 Simon McVittie 2013-02-25 20:54:02 UTC
(In reply to comment #13)
> maybe pam_systemd shoud set DBUS_SESSION_BUS_ADDRESS

Yeah, I wondered about that - but that doesn't actually make gdm's life any easier, because we decide whether or not to wrap the process in a dbus-launch long before we do the PAM handshake and find out whether pam_systemd is going to give us a DBUS_SESSION_BUS_ADDRESS (at the moment, it doesn't), or an XDG_RUNTIME_DIR for that matter (it does).

> What i mean is, if dbus-daemon is going to be socket activated, then setting
> DBUS_SESSION_BUS_ADDRESS to the socket location should always work, even in the
> absense of systemd --user right?

No, systemd as pid 1 only helps us get a system dbus-daemon socket-activated. We won't get a session dbus-daemon socket-activated unless there is something there to do the activating - namely a 'systemd --user' started on the user's behalf by logind.

If you have 1000 users, you don't want pid 1 to listen on 1000 sockets in case each of those users wants a session dbus-daemon :-)
Comment 16 Ray Strode [halfline] 2013-02-25 21:26:20 UTC
(In reply to comment #15)
> We won't get a session dbus-daemon socket-activated unless there is something
> there to do the activating - namely a 'systemd --user' started on the user's
> behalf by logind.
hmm if logind is starting systemd --user, how do we "trigger" it? It can't be just pam_open_session.  The greeter does "stuff" after the session is opened before it can be started.
Comment 17 Simon McVittie 2013-02-26 12:19:08 UTC
(In reply to comment #16)
> hmm if logind is starting systemd --user, how do we "trigger" it? It can't be
> just pam_open_session.  The greeter does "stuff" after the session is opened
> before it can be started.

pam_open_session calls login1.Manager.CreateSession, "officially" creating a logind login session.

systemd's TODO says logind should start user@`id -u`.service when a uid goes from 0 to 1 login sessions, and stop it when a uid goes from 1 to 0 login sessions. The patches on <https://bugs.freedesktop.org/show_bug.cgi?id=61129> implement that.

The assumption made by those patches is that default.target for user sessions starts a `dbus-daemon --session` and maybe some daemons like dconf, but nothing user-visible: GDM remains responsible for starting a gnome-session on the right display.

This is all very work-in-progress and I do not recommend actually applying it until the design issues I raised on the systemd mailing list have been solved: in particular, session services that really want to be per-uid (like dconf) are fine in this model, but session services that really want to be per-$DISPLAY (like at-spi-bus-launcher and parts of gnome-settings-daemon) are going to have problems.
Comment 18 Ray Strode [halfline] 2013-02-26 15:58:13 UTC
basically if pam_systemd's pam_sm_open_session triggers a dbus-daemon getting started, then I think that pam_sm_open_session should putenv the bus address of that dbus daemon it started.