Hello all,

a while ago I started experimenting with converting Ubuntu's upstart
graphical session to the user D-Bus and systemd session. This works
nicely and naturally for services which don't need $DISPLAY and are
not session specific, like pulseaudio or gvfs. However, others like
nautilus, mutter, unity etc. are absolutely specific to the
graphical session, so they need some shims to bind starting/stopping
them to the lifetime of the graphical session instead of the user. I
started a small discussion here in May [1].

I now have a prototype [2] which converts about half of the graphical
session to systemd units. We'll have a mini-sprint later in July to
complete/formalize this, but I'd like to settle some ground work
before. I don't think it makes much sense if every distro or project
comes up with their own naming schema and approach for this, as this
would again mean to introduce pointless diversion -- and one of
systemd's goals is to reduce these between distros -- and consequently
the inability to send/maintain these session service units upstream.
So let's see whether we can reach some agreement and recommendation
here and ship that upstream?

One proposed home-grown solution [3] is to introduce an
X11@${_DISPLAY}.target, but this isn't ideal: We shouldn't use "X11"
when Wayland/Mir become increasingly popular, and this is too
inflexible wrt. having multiple session types, such as "GNOME", "KDE",
"Unity", or "i3": Some services may want to start in all or several of
those (e. g.  gnome-settings-daemon is useful in an Xfce or i3
session), some others like gnome-shell are only being used in the
"GNOME" session.

There's two separate issues here, a "container" unit for the session
services and how to start/stop them with the session.

Container unit(s)
-----------------
All services/programs that should start in a particular graphical
session like "GNOME" or "Xfce" should be "bundled" by some wrapper
unit, so that they can be shut down as a group when the session ends.
target units would be the immediate natural choice, but are not
actually that suitable:

  * Stopping a target doesn't (by default) stop its requirements
    (but maybe I'm just missing something here).

  * You have to pre-define them, so we would need to have on-disk
    units for all session types like graphical-xfce.target,
    graphical-gnome.target, etc. Alternatively one could use templates
    like graphical@xfce.target, though. I actually considered/tried
    that first as it's the natural thing to start with, but there was
    still the above problem, so that didn't help.

So I went with slices in my prototype; they can be made up on the fly
(for new session types) and nicely destroy their
requirements/constituents when they get shut down, and thus pretty
well exactly provide what I need.  I created

|   [Unit]
|   Description=User systemd services for graphical session

This on-disk unit isn't strictly necessary, but good to have an useful
description, and it's more obvious that way where you should place
your services into as it even exists when it's stopped.

A service then looks like

|  # gnome-settings-daemon.service
|  [Unit]
|  Description=GNOME Settings Daemon
|
|  [Service]
|  ExecStart=/usr/lib/gnome-settings-daemon/gnome-settings-daemon
|  Restart=on-failure
|  Slice=graphical.slice

i. e. the magical thing is the "Slice=" so that the service goes down
with the session.

The actual session types are then defined in sub-slices such as
graphical-xfce.slice. They don't need to be declared, but of course
the package that ships /usr/share/xsessions/xfce.desktop could ship a
graphical-xfce.slice unit to give it a nicer name if it wishes. But
this isn't a requirement, and thus doesn't block a step-by-step
migration.

This container unit is what I'd like to propose and ship upstream, as
every session service unit will need to reference it. So need to set a
convention.


Top-level programs and dependencies
-----------------------------------
A session type like "GNOME" or "KDE" then defines which top-level
servcies it wants. E. g. if we want to start gnome-session in the
"gnome" and "unity" sessions, "unity7" only in the "unity" session,
and xeyes in any graphical session, then we'd have the following
enablement links:

| usr/lib/systemd/user/graphical-gnome.slice.wants/gnome-session.service → 
../gnome-session.service
| usr/lib/systemd/user/graphical-ubuntu.slice.wants/gnome-session.service → 
../gnome-session.service
|
| usr/lib/systemd/user/graphical-ubuntu.slice.wants/unity7.service → 
../gnome-session.service
|
| usr/lib/systemd/user/graphical.slice.wants/xeyes.service → ../xeyes.service

There will be relatively few of those, though, as most other stuff
is being handled as dependencies (Requires=/Wants=) of those top-level
services: gnome-settings-daemon, gnome-panel, etc.

At some point gnome-session might go away entirely and its top-level
dependencies (mutter, nautilus, etc.) be replaced with enablement
symlinks. This then needs to model gnome-session's stages, but this
should translate to several successive targets naturally, just like
sysinit → multi-user → graphical on the system side.


Start/stop of graphical.scope
-----------------------------
Ideally we could hook the startup of graphical.slice into the system
logind scope; but as the user systemd does not "see" the
systemd users, this isn't possible. So for now pretty much the only
way is to go via an /X11/xinit/xinitrc.d (Fedora) or
/etc/X11/Xsession.d/ (Debian) script like:

| $ cat ./etc/X11/Xsession.d/98systemd-graphical-session
| if [ -x /usr/share/systemd-graphical-session/session-wrapper -a -e 
/run/systemd/users/`id -u` ]; then
|     STARTUP="/usr/share/systemd-graphical-session/session-wrapper $STARTUP"
| fi

| $ cat ./usr/share/systemd-graphical-session/session-wrapper
| #!/bin/sh
| systemctl --user restart graphical-${DESKTOP_SESSION}.slice
| $@
| systemctl --user stop graphical.slice

Due to the existing distro fragmentation these wrappers will have to
stay distro specific/downstream for the time being; but that's okay,
as graphical session units don't need to know about this mechanics at
all. Of course it'd be fine to ship the Fedora variant upstream,
together with xorg/50-systemd-user.sh. (My hope is that over time the
above wrappers will become obsolete and display managers start/stop
that unit directly, but that isn't a blocker.)


I'd like to drive this forward, so that we can put the necessary infra
(the X session wrapper and the top-level graphical.slice) into
upstream and our distro packages and then start submitting session
units to GNOME/KDE/Xfce/etc. At the moment nobody is doing this,
because this feels like some kind of chicken-egg problem.

We can (and will) of course bikeshed about the details, unit
types/names, etc., but I guess step one is to discuss/agree that we
want to start standardizing session services in systemd.

Feedback appreciated!

Thanks,

Martin


[1] https://lists.freedesktop.org/archives/systemd-devel/2016-May/036440.html
[2] https://git.launchpad.net/~pitti/+git/systemd-graphical-session/tree/
[3] https://lists.freedesktop.org/archives/systemd-devel/2016-May/036449.html
-- 
Martin Pitt                        | http://www.piware.de
Ubuntu Developer (www.ubuntu.com)  | Debian Developer  (www.debian.org)

Attachment: signature.asc
Description: PGP signature

_______________________________________________
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel

Reply via email to