Friday, August 23, 2013

Using Systemd to Manage User Sessions

WARNING: This process doesn't work any more. Systemd user sessions are still experimental and volatile and this method no longer works.

If you haven't heard of systemd you should take a look. Basically it is a new /sbin/init process (PID 1). But systemd doesn't stop there, it can also be run as a user to manage arbitrary processes. This article is about replacing the session-manager that comes with your desktop environment (gnome-session, xfce4-session...) with a full-featured process manager.

Why Use a "better" Session Manager

There are a number of reasons for doing this including better process management and desktop independence. All desktop environment session managers I have experienced are lacking in a number of ways including logging, managing my processes and easy starting/stopping.

In general desktop session managers just pass stdout/stderr through the session manager, while this is okay because I can see the process's output, there is no easy to filter logs by process, also logs are generally non-persistant. When it is only the desktop components (window manager, panel,...) that isn't a big deal but if we want to run more processes a better logging system will become more important. Systemd has a closely integrated logging framework called journald, it ensures the time and date is present on all logs and sorts them by process. All stdout and stderr are captured so the processes you start probably don't have to be modified in order to be logged, which is useful as your mail client probably doesn't support a fancy logging framework.

By moving away from the DE's session manager we aren't locked into their default components anymore. Many people may not find this important but I mix-and-match applications my preference,generally not using one desktop's components. I often switch my components but running openbox as a window-manager with awn panel and xfdesktop is not uncommon for me, I also like metacity as a window manager. The story is that I can run whatever processes I want rather than what the authors of the desktop environment thought would be best. I can also manage my email and XMPP clients as well as clipboard managers, torrent clients and whatever other processes I desire.

The session managers that come with desktop environments don't usually provide good support for starting and stopping processes easily, if at all. The assumption is that you never need to stop your window manager. systemd, being just a process manager has strong support for starting and stopping processes, both automatically and manually.

Basically, you are replacing a simple, purpose-built session manager, that is a minor part of a larger project, with a full featured program that is dedicated to managing processes. They both do the same thing on the surface, but the configurability and polish are apparent when using systemd.

Switching Over

The first step is starting systemd on login. As usual, the Arch Linux Wiki has some fantastic docs covering many setups. The way I do it, and the way I am going to cover here is using ~/.xinitrc, I would recommend this way as it is supported by a variety of display managers and the commandline (startx). If you want to launch systemd a different way you are on your own (well, you have the wiki, it is pretty fantastic).

If you are currently launching your programs from .xinitrc it probably looks something like this.

#!/bin/sh
#
# ~/.xinitrc
#
# Executed by startx (run your window manager from here)

xbindkeys &
parcellite &

awn &
xfdesktop & 

xscreensaver -nosplash &
nm-applet &

seafile-applet &
thunderbird &
qbittorrent &
gajim &

exec xfwm4

Here you are launching a bunch of (unmonitored) process and then starting your window manager (also unmonitored), and blocking until it exits. If you are using a desktop environment your exec line will probably start the desktop session rather than just the window manager (ex: exec gnome-session). Since systemd is going to manage all of your processes you ~/.xinitrc becomes:

#!/bin/sh
#
# ~/.xinitrc
#
# Executed by startx (run your window manager from here)

exec /usr/lib/systemd/systemd

Now systemd will start when you launch your X session. When systemd beings it loads default.target, for exactly what targets and services are see the systemd documentation (man systemd.{unit,target,service}), but the basic concept is that a target starts services. So you can have different targets that start different sets of programs. In this example we will just create a target called graphical.target but other targets can be created the same way.

Starting Processes

All of the config files (herein "units") will be stored in ~/.config/systemd/user/, you could also add it to the system directory (/usr/lib/systemd/user/) if you so desire.

First create your graphical.target

[Unit]
Description=Graphical Session

# Allow switching to this target.
AllowIsolate=true

[Install]
# When `enabled` it will be aliased to `default.target`.
Alias=default.target

Once that is present you can start systemd with that target by changing the commandline to /usr/lib/systemd/systemd --unit graphical.target. You can also switch from any target to this target using systemctl --user isolate graphical.target while systemd is running. However, the easiest way to set it to the default is linking it to default.target. The command systemctl --user enable graphical.target will do that for you.

Next you have to create a service file for every process you want to start. These are fairly straight forward, see this metacity.service as an expample.

[Unit]
Description=Metacity Window Manager

[Service]
# Path must be absolute.
ExecStart=/usr/bin/metacity

# If you prefer you can use `env` to do do a path lookup.
#ExecStart=/usr/bin/env metacity

# If this program crashes unexpectedly, restart it.
# Look at `man systemd.service` for the plethora of
# restarting options.
Restart=on-abort

[Install]
WantedBy=graphical.target

Pretty straight forward. Just create one for every one of your services and use systemctl --user enable ${name}.service to run them by default. This is all you have to do and you should have a fully functioning system. To save you the trouble of writing many unit descriptions I have a repository of configs for apps that I use. It is by no means extensive but it may save you a couple of key strokes. Feel free to submit your own back to the repo.

Profit

After a reboot (or just logging back in), you should have all of your processes managed by systemd. They will be automatically restarted if they crash and other than that work pretty much like they used to. However, if you with there are many options you can use to fully customize how they run, you can set up positive and negative dependencies as well as controlling the environment, and just about whatever else you want.

If you want to check the status of a process just run systemctl --user status gajim.serive and it will show you how your XMPP client is doing. It also displays a couple of lines of output, if you want the full logs use journalctl --user-unit gajim.service and you can see it all. You can also follow the output as it happens with -f as well as many other options.

Thoughts

After using systemd for a while I am very happy, capturing the output of these programs has proved invaluable many times over already, from debugging certificate issues in my XMPP client to crashes in my bluetooth applet, I also have no desktop dependence and can switch up my programs on a daily basis if I desire, just a disable here and an enable there. I can also change my window manager mid-session which is generally not possible using .xinitrc as my session would end as soon as my window manager exits. This means that I can try out new configurations without messing up my known-good state that I know will be there if I `systemctl --user isolate graphical.target`.

So in conclusion:

  • It manages you programs, much like you are used to.
  • For day-to-day usage it won't be much different.
  • However, when you do use the extra features you will appreciate them.
  • No lock-in, leaves you free to use whatever programs you want.

No comments:

Post a Comment