GNOME 3.34 is now managed using systemd

If you are already using GNOME 3.34, then most likely your session is managed using systemd right now. For a long time now we were already running a systemd instance for every user, which is used to launch DBus and for DBus activated applications. So, with GNOME 3.34, we finally took the next step and moved the rest of the session over to run using systemd.

From a user’s perspective nothing should have changed and at this point I believe that most regressions have been dealt with. Neither will this change affect application developers for the time being as XDG autostart files continue to be supported and are prefered at least for the time being.

The great thing is, that this enables further improvements. There has been a lot of work to allow Xwayland to be started on demand and systemd plays a small part in that feature. Similar, we will also be able to shut down services that are only needed if specific hardware is present (e.g. smartcards). Also, using systemd it is now easy to sandbox all components which will give you an extra bit of security.

That said, there are a few changes, concepts and general information that is worth mentioning.

Slices, scopes and user sessions

On a systemd managed system each user is assigned a user-X.slice (systemd.slice(5)) and the user’s session will be run in a session-Y.scope (systemd.scope(5)). You can also see a few other user specific units on the host, including user@X.service, which is the user’s systemd instance. This is a separate systemd process for the user and it will shut down again if the user is not logged in anymore.

With the systemd move, not only DBus activated applications and services, but rather your entire session is now launched using your user’s systemd instance. This has a few side effects that may seem odd at first. For example, the previously mentioned session-Y.scope which used to contain over 200 processes is now down to a mere 4 processes. Another side effect is that it got harder to understand which session a process belongs to (this is relevant for a number of services) or that ps will not show a tty anymore.

But, we have addressed these side effects and hopefully there are no regressions at this point. Your GNOME session is still invariably bound to the session-Y.scope (e.g. using loginctl kill-session continues to work reliably). And services have been updated to understand the new regime and pick the correct session in all cases. To handle all this, new API was also added to the systemd DBus interface and further improvements may happen in this area.

Trying it out

So, if you have GNOME 3.34, you can now apply all the neat tools that systemd has manage your user’s session. Just remember to add the --user option, and things should work as expected. A good candidate for trying all this out is gsd-media-keys.

If we look at systemctl --user, we’ll find two entries:

  • gsd-media-keys.target
  • gsd-media-keys.service

Note that failed units will not show up in the list, so it is advisable to always check the log if you suspect a service failure. Unfortunately this is needed so that you can reliably log in again after a session failure.

We can control gsd-media-keys.target (not gsd-media-keys.service), so you can try stopping and starting it and you will notice that most global keybindings will stop and start working.

  • systemctl --user stop gsd-media-keys.target
  • systemctl --user start gsd-media-keys.target

We can also pull up the log messages for the service from journalctl.

  • journalctl --user -u gsd-media-keys.service

But, unfortunately, it will not log much information by default. But, knowing systemd and GLib environment variables we can run:

  • systemctl --user --runtime edit gsd-media-keys.service

and write:

  • [Service]
    Environment=G_MESSAGES_DEBUG=all

This enables debug messages when the service is restarted next. The configuration will not persist as we passed --runtime. If you now restart gsd-media-keys.target and inspect its log again, you will notice that it contains a lot more information.

Developing GNOME

If you have a development version of GNOME installed somewhere outside of your normal path (e.g. jhbuild) and use this to log in, then you may need to update your setup. In jhbuild there is an example jhbuild-session script that ensures that the correct unit files will be used. The relevant lines copy them into the user’s $XDG_RUNTIME_DIRECTORY and reload the systemd daemon.

On a final note, I would like to thank everyone who has worked on this in the past. As far as I know, the first experimentations were done by Canonical, in particular Iain Lane did a lot of work and submitted the first patches. I picked up this work and made plenty of improvements to get it over the finishing line.

If you don’t have GNOME 3.34 yet, then try it out by installing Fedora 31 beta or your favourite distribution that includes GNOME 3.34 already.

40 thoughts on “GNOME 3.34 is now managed using systemd”

    1. Yep, you can do this. Have a look at how gnome-settings-daemon already does it. It boils down to adding X-GNOME-HiddenUnderSystemd=true to the XDG autostart file and then providing your own systemd service.

      That said, please don’t consider the target names used in GNOME to be stable at this point. Tracker should be fine as it can be updated in sync with GNOME if a change happens. But that will not be the case for other projects.

      If you want to be on the safe side, then it probably is better to go through DBus activation though.

  1. Very nice work!
    Running GNOME 3.34 under Debian sid here. I didn’t even notice the switch until you blogged about it.

    One regression I noticed is, that applications started via XDG autostart start too early, before the shell (and in my case the kstatusnotifier extension) is loaded. The result is, that those applications are not shown in the systray. It seems X-GNOME-Autostart-Phase=Application is not really having an effect anymore.

    For the time being, I start the nextcloud client via a shell script and put a sleep 10 before I exec the binary. I obviously want to get rid of this hack.

    Do you consider the above a bug in gnome-session and should I file a corresponding bug report?

    1. It is true that applications start earlier currently. The effect currently means that XDG autostart applications may launch before the gnome-settings-daemon processes have been fully loaded. In most cases, including this case, that should make no difference though.

      What I suspect happened in your case is that the gnome-settings-daemon startup was simply always “slow” enough for the shell to have loaded the relevant extension already. This is something that may have worked but has always been fragile. Applications should probably notice it when the kshellnotifier extension is loaded later on.

      That said, technically there is a bug here. We should only start launching the XDG autostart files in the Application phase after the session is fully initialized. We already have one such synchronization point and we can add another one easily. Please file a bug about this against gnome-session and we can address this. However, as said above, it may not fix the issue you are seeing.

  2. My man, congratulations to you and Iain on this fabulous work. It’s been a long time coming and I’m glad we’ve finally got rid of gnome-session.

    One thing that I’m interested in is the ability to assign cgroups to specific applications. Things like web browsers frequently will eat CPU and of course on a laptop that eats battery. Would we be able to apply default cgroups for general launching of applications and maybe a specific groups of apps? I queried this elsewhere, and initially people thought it was not possible, but Lennart said it was. So I’m hoping it is something that we can have in scope.

    1. gnome-session actually still exists. There are still tasks it does and it is also needed for XDG autostart files (that part might change).

      These changes do not affect launching of normal applications. Most of them are already launched using DBus activation anyway and in some cases that means that a systemd service is started (e.g. gnome-terminal). One can probably restrict applications a bit that way, but I suspect that Flatpak might provide a more fitting infrastructure to do these kind of things.

    2. To “assign cgroup to specific applications”, those applications should run as separate systemd –user units. The most obvious way is to start them as units, as e.g. various gnome services described in this article are. But other ways are possible, for example using scopes or systemd-run.

      Once a process is running as a separate systemd unit, normal resource control mechanisms supported by systemd apply. There’s a gotcha here: for unprivileged units, like all systemd –user units, cgroups v2 hierarchy is required (which actually is now the default in Fedora 31).

      For example:

      $ systemctl --user cat memcheck.service
      # /home/zbyszek/.config/systemd/user/memcheck.service
      [Service]
      ExecStart=sleep infinity

      MemoryHigh=200M
      MemoryLow=50M
      $ tail /sys/fs/cgroup/user.slice/user-1000.slice/user@1000.service/memcheck.service/memory.{high,low,max}
      ==> /sys/fs/cgroup/user.slice/user-1000.slice/user@1000.service/memcheck.service/memory.high /sys/fs/cgroup/user.slice/user-1000.slice/user@1000.service/memcheck.service/memory.low /sys/fs/cgroup/user.slice/user-1000.slice/user@1000.service/memcheck.service/memory.max <==
      max

  3. I’ve been pushing for similar changes in KDE/Plasma, it’s been a slow boring process splitting some of the core startup things, but we’re getting there too.

    I have some questions, maybe this isn’t the best forum, but you can direct me where to go.
    (I’ve also made absolutely no effort to just read your code)

    How do you handle knowing which desktop you’re loading and act accordingly? Are any parts built with a generator? How are third party .desktop files in autostart dirs handled?

    For a recent project, we experimented with an idea to make launching /all apps/ a systemd unit. We replaced the “start menu” code with a path that created transient units effectively calling (“systemd-run –user –scope –unit someDesktopFileName someExe”)

    It allowed for some useful UI grouping of running processes, and eventually applying better resource management at runtime (as firefox is too many processes normally) is that a direction gnome could also be interested in?

    1. How do you handle knowing which desktop you’re loading and act accordingly?/quote>

      We are using a template unit for this. So gnome-session launches gnome-session-{x11,wayland}@SESSION.target which then pulls in everything else.

      Are any parts built with a generator? How are third party .desktop files in autostart dirs handled?

      Right now we are still using the old code for all of this and almost nothing has changed for these applications. The idea of using a generator has been floating around, but unfortunately we would need a separate daemon for this to work. This is because we have a feature where the autostart application is started if a certain configuration key is active. Something that simply cannot be mapped to any Condition rule in systemd.

      For a recent project, we experimented with an idea to make launching /all apps/ a systemd unit. We replaced the “start menu” code with a path that created transient units effectively calling (“systemd-run –user –scope –unit someDesktopFileName someExe”)

      I would love to see these kind of changes. For any dbus activated application something similar is already happening in many cases. But we are not doing this otherwise, which is actually creating a few issues currently.

      In that regard, I am wondering if we should set BindTo for such units to guarantee that they are killed at log out.

      1. Thanks for the replies.

        >I would love to see these kind of changes.

        Where would be a good place to follow that last point up?

        P.S ski 2020?

    2. “ I’ve been pushing for similar changes in KDE/Plasma”

      That’s actually pretty awful, some the *BSD’s also depend on KDE software for desktop usage, where are the non-systemd dependent UNIX’s to go if all open source software projects go into that direction?

  4. I am running Debian sid, and I think I upgraded the system yesterday. This morning, the mouse and the keyboard would be frozen in the gdm3 login screen. There probably was only the background image and a mouse pointer on the screen. The mouse pointer would move for maybe the first half a second and then freeze.

    The whole system was not frozen; I was able to log in via sshd. I temporarily resolved the problem by downgrading gdm3 from 3.34 to 3.30. (Actually, I did not get a gdm3 screen at all, maybe because I did not downgrade all needed packages, but I was able to invoke “startx” from the text-based virtual console.)

    I did not notice anything obvious in the logs.

    Maybe the issue will be resolved in a few days when more packages are updated. I thought that it would be good to mention this, in case someone else runs in to the same issue.

    1. There is one way that I can imagine that such an issue is related. It is a bit of a long shot, but logind/mutter may have gotten confused about which session is active. This would point to a version mismatch though, so it could be a good idea to first check that you are on 3.34 for all components (gnome-shell, mutter, gdm and maybe more).

      If it happens again, you could check whether the corresponding session is shown as active using loginctl. Also, maybe try switching VTs using chvt or loginctl activate.

      That said, it may also well be that this is completely unrelated to these changes.

      1. I did not have time to debug it yesterday, and the problem was magically fixed today (after installing some updates yesterday). I think that all packages were on 3.34 already yesterday morning. Today morning’s update included gnome-session 3.34.0-3 and some others. Before updating today, I did get a gdm3 screen, but when logging in, I would get the “something was wrong” popup screen.

        1. Aha! I think this might have been caused by an issue in gnome-initial-setup that we fixed a while ago. Good to hear this has been resolved for you.

  5. Aha, this must be why software such as Aruba VIA (a crufty QT program) are now no longer obeying theme settings when I first log in, and must be restarted to pick up my dark theme.

    And maybe why own cloud and Nextcloud no longer reliably show up in the app indicator area (why these two have not adopted libcloudproviders yet is an endless source of frustration to me).

    1. Yeah, that sounds like the issue I described more in reply to Michael earlier. We are not synchronizing application auto-starting with some processes right now, which explains the dark theme issue at least.

      The right thing to do with this is to open a bug against gnome-session. It should not be hard to deal with. But, as said before, it is unlikely to guarantee a fix for all cases.

  6. One of your tips can cause gpg to break. To explain:

    I ran the settings for adding G_MESSAGES_DEBUG=all to gsd-media-keys :
    systemctl –user –runtime edit gsd-media-keys.service

    and it broke gpg-agent. Why?

    Because I launch my terminals with hotkeys, they inherit the environment from gsd-media-keys. When I use something requiring a gpg key (git, gpg, etc.) a gpg-agent is launched with G_MESSAGES_DEBUG=all environment variable. When gpg-agent launches pinentry-gtk-2 or pineentry-gnome3 they both break because the G_MESSAGES_DEBUG causes pinentry-gtk/gnome3 logging to stdout which is where the communications occurs between pinentry and gpg-agent.

    a fix for me was to put “unset G_MESSAGES_DEBUG” in my .bashrc. This took my a while to figure out what was happening and why this happened, so I figured I would report this here.

    1. You should only enable debug logging in that way if you want to debug gsd-media-keys. 🙂

  7. So what about the other OSes like the BSDs and other non-systemd systems that run GNOME? Just to hell with them?

    1. The old startup mechanism is still used for legacy applications and is fully functional. It has been in maintenance mode for a long time. Should we start using generators in the future (this is unlikely to happen very soon though), then this code would become obsolete on systems where systemd is available.

      So yeah, in the long run that might increase the burden on the non-systemd ecosystem slightly as they may need to provide patches should things break. Other than that, I expect that the still working code will simply continue to exist indefinitely.

  8. I looked into this, and these are some findings.
    I assume that moving the desktop processes management to systemd aims to deliver some of systemd’s goals. Of these, two are: cross-distribution (complex) way of managing and configuring a system; dynamic on demand activation of daemons.
    This is not what I see now, probably it is too early.

    These examples show what I mean.

    On a normally booted system:
    $ systemctl get-default
    graphical.target
    $ systemctl –user get-default
    default.target
    Now, if you dare, do:
    $ sudo systemctl default
    nothing happens because it is idempotent: the system already was at default.target (if it wasn’t, blame gnome-software offline update feature. Did you save everything before, right?)
    Now save everything and do:
    $ systemctl –user default
    and find yourself logged out at the gdm greeter. This happens on Debian Sid with gnome-session and gnome-settings-daemon 3.34.1-1 which carry the news announced here.

    systemd has “presets” to “encode policy which units shall be enabled by default and which ones shall be disabled.” (man systemd.preset).

    The 16 pairs of unit files {.service,.target} newly provided to start all gnome-settings-daemon plugins, see them with:
    $ systemctl –user list-unit-files gsd*
    force start every possible plugin.
    Also, they will forcibly crash the session (“whale”) if an unnecessary plugin fails. See the OnFailure key in:
    $ systemctl –user cat gsd-a11y-settings.service
    and see it in action doing:
    $ sudo chmod -x /usr/lib/gnome-settings-daemon/gsd-a11y-settings
    $ systemctl –user exit # This works as assumed.
    Login again to meet the whale! (Read: you cannot login to gnome shell anymore.)

    The new units provided are static (there is no [install] section). The package gnome-settings-daemon-common installs symlinks in
    /usr/lib/systemd/user/gnome-session-initialized.target.wants
    This defeats the preset system, and prevents the disable command from working:
    $ sudo systemctl –user –global disable gsd-a11y-settings
    $ sudo systemctl –user –global disable gsd-a11y-settings.target
    $ sudo systemctl –user –global disable gsd-a11y-settings.service
    See: nothing has been disabled . Contrast with another user unit having an [install] section:
    $ sudo systemctl –user –global disable pulseaudio.service
    Removed /etc/systemd/user/default.target.wants/pulseaudio.service.
    Removed /etc/systemd/user/sockets.target.wants/pulseaudio.socket.
    On demand activation provides an easy way to keep resources requirements low: just don’t use what isn’t needed. Next, one can disable unwanted services that are enabled using an [install] section. The way done here, forcibly starting and enforcing failure if not, is at odds with systemd’s goals.

    1. Pretty much everything you are describing is exactly the expected behaviour.

      Really, this is not about making it all configurable for users. It is about creating a consistent way that GNOME can manage its own services. Also, keep in mind that the systemd user service is not just managing your graphical session. It may also be managing further services the user has running (including e.g. from an ssh login).

      If systemctl --user default causes the GNOME session to log out, then there may be a small bug somewhere. Probably a simple issue to fix, even if I would not consider it very important.

      You are right that we could change the packages to create symlinks in /etc/systemd/user for the .wants targets at package installation time. While this may more correct in principle, it does not really give users any advantages other than making it easier to break the GNOME session. And the pattern used by GNOME here actually matches e.g. what pipewire does and what is done by a lot of system services (really, look in /usr/lib/systemd/system/*.wants).

      Note that users and administrators can still mask the gsd-.target units to prevent startup of the services.

      1. If systemctl --user default causes the GNOME session to log out, then there may be a small bug somewhere.

        Correction. This is exactly what is supposed to happen. Running systemctl --user default causes only units that are started by default to run afterwards (i.e. it starts default.target with the isolate mode). As GNOME is a “service” that is started dynamically later on it has to be stopped. This makes total sense, it would not make sense to try to run GNOME when you log in via SSH or on the console.

  9. Masking the units makes it impossible to start them at all with `systemcltl –user start`. The desire is they do not autostart at login, not they be totally unavailable.
    The way pulseaudio.service unit behaves is how the gsd-*.service units should do too.
    The “whale” in case some gsd plugin does not start at login makes no sense. I can always issue `systemctl –user stop gsd-a11y-settings.target` after login without crashing anything.
    I’ll work around diverting the symlinks created by the package gnome-settings-daemon-common so they do not get reinstalled on updates, and adding a drop-in for the gsd.*.service files with an [install] section, leaving the target files unused.

    I have not investigated why `systemctl –user default` logs out, but I appreciate you agree this is a bug. Should I open an issue on gitlab?

  10. … adding a drop-in for the gsd.*.service files with an [install] section,

    That is not really enough in general though. You also need to ensure symlinks are up to date in /etc/systemd/user and enabled by default.

    The “whale” in case some gsd plugin does not start at login makes no sense.

    This is the desired behaviour, whether you agree with it or not. The corner case you constructed by crippling the executable is rather extreme and we do want this if it crashes repeatedly.

    1. >This is the desired behaviour, .. The corner case… WE DO WANT /TO CRASH/
      Mine was not intended to be a corner case, but a simulation of a failure.
      Per Murphy law, one should plan for the case when something fails, and limit the damage.
      But here, maximum damage could happen for a really good thing: the day when gsd-wacom exits immediately if there is no Wacom tablet present.
      That day, Gnome users will be unable to login to the graphical desktop!

      1. Mine was not intended to be a corner case, but a simulation of a failure.

        Haha. Well, tell that to the people who wrote gnome-session and hardcoded this exact behaviour in 2011 or even earlier. And I am not aware of complaints other than yours now that it has been copied to systemd.

        1. Your attitude will not improve improve Gnome. A quick search finds
          https://bugzilla.gnome.org/show_bug.cgi?id=671694
          Reported: 2012-03-09 05:00 UTC by Matthias Clasen

          Links to a duplicate with the words of a past maintainer of gnome-session:
          https://bugzilla.gnome.org/show_bug.cgi?id=648384#c3

          William Jon McCann 2012-03-07 22:02:31 UTC

          Yeah this is quite bad. The designed/intended behavior is for the “fail whale” to only be shown for unrecoverable errors. Basically when the user session oops its pants.

          1. In that case the error handling code that shows the screen was misbehaving though. Not something that is happening with the current systemd code.

            So yeah, it is fully intentional to log the user out. With the assumption that a clean log-in will hopefully fix things …

    1. No really, this is just a question of what you prefer. Is it better to log out a user and hope that the session runs properly again on next login or is it better to try to keep running with an entirely broken session where things are likely to fail in unexpected ways.

      That gnome-settings-daemon bug you linked here is a case where a logout actually helped a lot. Sure, the user may still not be able to open the gnome-control-center page the next time they log in. However, the next login works fine and at least logging out and back in will recover important functionality like screen blanking, suspend handling and display backlight control. So yeah, I would argue that the error behaviour was sensible for that bug.

      So yeah, I would actually continue to argue that for most users the forced-logout is the better design decision in that case.

      Seriously, if you really don’t want this then go ahead and mask gnome-session-failed.target. Then you will never see the fail-whale.

    2. One more note. This is an OnFailure action. It will only be triggered if the service crashes more than 5 times within a 10 second period. If it crashes less often, then the session will recover gracefully.

      1. Have been using and acting as sysadm for some KDE installations since about 15 years ago. Before it was Windows NT, and before MS/DOS (ever heard of “terminate and stay resident” eating in 640kB of available ram?), and before…. Hardware grew more powerful, but software ever more greedy. I still have in production a Windows NT Server on consumer hardware from 1996 for a legacy application; I can assure that it’s desktop is way snappier than KDE on rotational disk on a 5 year old laptop.
        Recently advertised “Gnome 3.34 drastically improved responsiveness” brought me to evaluate it. Seen it, liked it, I am going to switch some desktops from KDE to Gnome.

        I am unfamiliar with Gnome code base. Looking around in gnome-session and gnome-settings-daemon on Gitlab, I cannot see why TODAY in Gnome 3.34 all the gsd plugins should be considered “RequiredComponents”. Perhaps in the past, don’t know, gsd was providing something essential to the Gnome desktop. To a newcomer to Gnome, it looks like an obsolete requirement, made redundant by changes in the consumers of its services. Proof: I am writing this in Gnome 3.34, some hours ago I did
        $ systemctl –user stop gsd-*.target
        and pretty much nothing noticed. The journal is clean. Just, I have no global keyboard shortcuts now, but no major failure either.
        This makes me confident that the effort to trigger failure on the whole Gnome session if any of gsd plugins fails at login time is really not warranted: there is no use case for this.
        But it was a minor technical point.

        The general point I am interested in is: when things will settle on systemd as a desktop session manager, session services be started on request, stop themselves when idle, be configurable with the standard systemd idiom, and all this be implemented in a Freedesktop.org standards compliant fashion, without “shenanigans” or “X-GNOME-HiddenUnderSystemd=true” hacks.

        pulseaudio.service, for the obvious reason it comes from the same author as systemd, shows the way to go: sockets activated, manageable, presettable, also confined. Still lacks idle timeout exiting: nobody’s perfect!
        Same is gpg-agent.service: finally the agent is fully socket activated, and not launched in the Xsession startup scripts!
        There is also emacs.service to look at, which surely has been written by and for people with long experience and high expectations, and awaits there to be enabled for those who have uses for an emacs server ;-).

        But, at Gnome’s house, there are different thoughts.
        I could be willing to hide my dates in the drop down calendar in certain circumstances, no? So, I stop evolution-calendar-factory.service, just to see gnome-shell immediately restarting it! Is managing session daemons gnome-shell’s or systemd’s duty? Will see…

        Thank you for bearing with me.

        1. I cannot see why TODAY in Gnome 3.34 all the gsd plugins should be considered “RequiredComponents”.

          I can see how at first glance things seem to be running completely fine. And, I can also see that you may argue that e.g. printer notifications are not very important. However, there are a lot of features that are essential to get a proper user experience and for core GNOME features to work. And even if you might not need them (e.g. no HiDPI display, no wacom tablet, not using night light, …) it is really important for these things to always work.

          … So, I stop evolution-calendar-factory.service, just to see gnome-shell immediately restarting it

          This is DBus activation and it is an important core functionality that DBus provides. It is also used by a lot of system services and it is the reason that idle shutdown of services is possible in a lot of cases. DBus pre-date systemd by a long time and the automatic activation is handled by the DBus daemon. The .service is “just” used for sandboxing.

  11. As someone proficient in systemd, I appreciate this change.

    I know Gnome 3.34 is supposed to be faster because of unrelated changes, but I’m curious if there was before/after benchmarking done for this change in particular.

    It seems like it would impact Gnome’s start up time one way or the other.

    1. …, but I’m curious if there was before/after benchmarking done for this change in particular.

      I have not done any benchmarking. That said, GNOME already started the processes at the same time where possible. So the fact that systemd can handle more complex dependencies does not help us for the GNOME startup. So I expect a really tiny slowdown due to additional overhead in a few places.

Leave a Reply

Your email address will not be published. Required fields are marked *