[[systemd]] offers users the ability to run an instance of [[systemd]] to manage their session and services. This allows users to start, stop, enable, and disable units found within certain directories when systemd is run by the user. This is convenient for daemons and other services that are commonly run as a user other than root or a special user, such as [[mpd]].

[[systemd]] offers users the ability to run an instance of [[systemd]] to manage their session and services. This allows users to start, stop, enable, and disable units found within certain directories when systemd is run by the user. This is convenient for daemons and other services that are commonly run as a user other than root or a special user, such as [[mpd]].

+

+

{{Note|systemd --user sessions are not compatible with -ck patchset}}

== Setup ==

== Setup ==

=== startx ===

=== startx ===

+

+

{{Note|This step is unnecessary if you plan to use autologin.}}

Users should first set up systemd-logind to manage their session. If [[systemd]] is running as the system init daemon, then this is already happening.

Users should first set up systemd-logind to manage their session. If [[systemd]] is running as the system init daemon, then this is already happening.

−

Next, the user must launch systemd by putting the following in their {{ic|~/.xinitrc}} '''before the exec line''':

+

Next, the user must launch systemd by putting the following in their {{ic|~/.xinitrc}}.

−

{{bc|systemd --user &}}

+

{{bc|systemd --user}}

+

If the user is not launching the window manager through systemd --user, then {{bc|systemd --user &}} should be used and launched like anything else in {{ic|~/.xinitrc}}, before execing the window manager.

After starting X, the user can check whether their session is now being managed by systemd-logind with the following command:

After starting X, the user can check whether their session is now being managed by systemd-logind with the following command:

+

{{bc|<nowiki>

{{bc|<nowiki>

$ loginctl --no-pager show-session $XDG_SESSION_ID | grep Active

$ loginctl --no-pager show-session $XDG_SESSION_ID | grep Active

</nowiki>}}

</nowiki>}}

+

If this command prints {{ic|1=Active=yes}}, then the user is now using systemd-logind to manage their session. The user should remove any instances of '''ck-launch-session''' or '''dbus-launch''' from their {{ic|~/.xinitrc}}, as those commands are unneeded.

If this command prints {{ic|1=Active=yes}}, then the user is now using systemd-logind to manage their session. The user should remove any instances of '''ck-launch-session''' or '''dbus-launch''' from their {{ic|~/.xinitrc}}, as those commands are unneeded.

=== Display Managers ===

=== Display Managers ===

All of the major display managers are now using systemd-logind by default, so the {{ic|loginctl}} command from the previous section should work as stated. A user simply has to add {{ic|systemd --user}} as a program to be started by their desktop environment.

All of the major display managers are now using systemd-logind by default, so the {{ic|loginctl}} command from the previous section should work as stated. A user simply has to add {{ic|systemd --user}} as a program to be started by their desktop environment.

+

+

==== GNOME 3 (using GDM) ====

+

For users who wish to have GDM/GNOME 3 auto-start their {{ic|systemd --user}} session upon login, they just need to add a special log in session for this:

+

{{hc|/usr/share/xsessions/gnome-systemd.desktop|<nowiki>

+

[Desktop Entry]

+

Type=Application

+

Name=systemd

+

Comment=Runs 'systemd' as a user instance.

+

Exec=/usr/lib/systemd/systemd --user

+

</nowiki>}}

+

+

Make sure to choose the {{ic|systemd}} session option at the GDM login screen.

+

{{Note|This has only been tested with a pure GDM and GNOME 3 setup. For other set ups, YYMV. This method does not need the systemd user-session scripts installed.}}

=== Using systemd --user To Manage Your Session ===

=== Using systemd --user To Manage Your Session ===

Line 44:

Line 64:

Description=Window manager target

Description=Window manager target

Wants=xorg.target

Wants=xorg.target

−

Wants=myStuff.target

+

Wants=mystuff.target

Requires=dbus.socket

Requires=dbus.socket

AllowIsolate=true

AllowIsolate=true

Line 53:

Line 73:

This will be the target for your graphical interface.

This will be the target for your graphical interface.

−

Put together a second target called {{ic|mystuff.target}}. This will be 'WantedBy' all services but your window manager:

+

Put together a second target called {{ic|mystuff.target}}. All services but your window manager should contain a {{ic|WantedBy}} line, under {{ic|[Install]}}, pointing at this unit.

{{hc|$HOME/.config/systemd/user/mystuff.target|<nowiki>

{{hc|$HOME/.config/systemd/user/mystuff.target|<nowiki>

Line 68:

Line 88:

Next you need to begin writing services. First you should throw together a service for your window manager:

Next you need to begin writing services. First you should throw together a service for your window manager:

−

{{hc|$HOME/.config/systemd/user/i3.service|<nowiki>

+

{{hc|$HOME/.config/systemd/user/YOUR_WM.service|<nowiki>

[Unit]

[Unit]

Description=your window manager service

Description=your window manager service

Before=mystuff.target

Before=mystuff.target

After=xorg.target

After=xorg.target

−

+

Requires=xorg.target

+

[Service]

[Service]

−

Requires=xorg.target

#Environment=PATH=uncomment:to:override:your:PATH

#Environment=PATH=uncomment:to:override:your:PATH

−

Environment=DISPLAY=:0

ExecStart=/full/path/to/wm/executable

ExecStart=/full/path/to/wm/executable

Restart=always

Restart=always

Line 94:

Line 113:

If you want to have systemd automatically log you in on boot, then you can use the unit in user-session-units to do so. Enabling a screen locker for will stop someone from booting your computer into a nice, logged in session.

If you want to have systemd automatically log you in on boot, then you can use the unit in user-session-units to do so. Enabling a screen locker for will stop someone from booting your computer into a nice, logged in session.

−

If you installed user-session-units as listed above, then you must copy {{ic|user-session@.service}} to {{ic|/etc/systemd/system}} directory and edit the {{ic|user-session@.service}} (not the {{ic|user-session@yourloginname.service}}) and edit this line:

+

If you installed user-session-units as listed above, then you must copy {{ic|/usr/lib/systemd/system/user-session@.service}} to {{ic|/etc/systemd/system/user-session@yourloginname.service}}) and edit these lines:

{{Note|Notice the subtle change where the {{ic|%I}} become {{ic|%U}})}}

+

{{Note|Notice the subtle change where {{ic|%I}} is replaced by {{ic|%U}}}}

As well as an install section:

As well as an install section:

Line 110:

Line 131:

}}

}}

−

You will need to patch systemd to do this, so either using '''systemd-git''' from after [http://cgit.freedesktop.org/systemd/systemd/commit/?id=067d851d30386c553e3a84f59d81d003ff638b91 commit 067d851d] or patch it into systemd with the [[ABS]]. After 197, it should be in the mainline systemd.

+

or if you have no login manager:

+

+

{{bc|1=

+

[Install]

+

WantedBy=getty.target

+

}}

Add this line to {{ic|/etc/pam.d/login}} and {{ic|/etc/pam.d/system-auth}}:

Add this line to {{ic|/etc/pam.d/login}} and {{ic|/etc/pam.d/system-auth}}:

Line 116:

Line 142:

{{bc|session required pam_systemd.so}}

{{bc|session required pam_systemd.so}}

−

Because {{ic|user-session@.service}} starts on tty1, you will need to add {{ic|1=Conflicts=getty@tty1.service}} to the service file.

+

Because {{ic|user-session@.service}} starts on tty1, you will need to add {{ic|1=Conflicts=getty@tty1.service}} to the service file, if it doesn't exist already.

+

+

Once this is done, {{ic|systemctl --user enable}} {{ic|YOUR_WM.service}}

One of the most important things you can add to the service files you will be writing is the use of {{ic|1=Before=}} and {{ic|1=After=}} in the {{ic|[Unit]}} section. These two parts will determine the order things are started. Say you have a graphical application you want to start on boot, you would put {{ic|1=After=xorg.target}} into your unit. Say you start '''ncmpcpp''', which requires '''mpd''' to start, you can put {{ic|1=After=mpd.service}} into your ncmpcpp unit. You will eventually figure out exactly how this needs to go either from experience or from reading the systemd manual pages. Starting with [http://www.freedesktop.org/software/systemd/man/systemd.unit.html systemd.unit(5)] is a good idea.

One of the most important things you can add to the service files you will be writing is the use of {{ic|1=Before=}} and {{ic|1=After=}} in the {{ic|[Unit]}} section. These two parts will determine the order things are started. Say you have a graphical application you want to start on boot, you would put {{ic|1=After=xorg.target}} into your unit. Say you start '''ncmpcpp''', which requires '''mpd''' to start, you can put {{ic|1=After=mpd.service}} into your ncmpcpp unit. You will eventually figure out exactly how this needs to go either from experience or from reading the systemd manual pages. Starting with [http://www.freedesktop.org/software/systemd/man/systemd.unit.html systemd.unit(5)] is a good idea.

+

+

=== Other use cases ===

+

+

==== Persistent terminal multiplexer ====

+

+

You may wish your user session to default to running a terminal multiplexer, such as [[GNU Screen]] or [[Tmux]], in the background rather than logging you in to a window manager session. Separating login from X login is most likely only useful for those who boot to a TTY instead of to a display manager (in which case you can simply bundle everything you start in with myStuff.target).

+

+

To create this type of user session, procede as above, but instead of creating wm.target, create multiplexer.target:

+

+

{{bc|1=

+

[Unit]

+

Description=Terminal multiplexer

+

Documentation=info:screen man:screen(1) man:tmux(1)

+

After=cruft.target

+

Wants=cruft.target

+

+

[Install]

+

Alias=default.target

+

}}

+

+

{{ic|cruft.target}}, like {{ic|mystuff.target}} above, should start anything you think should run before tmux or screen starts (or which you want started at boot regardless of timing), such as a GnuPG daemon session.

+

+

You then need to create a service for your multiplexer session. Here's a sample service, using tmux as an example and sourcing a gpg-agent session which wrote its information to /tmp/gpg-agent-info. This sample session, when you start X, will also be able to run X programs, since DISPLAY is set.

+

+

{{bc|1=

+

[Unit]

+

Description=tmux: A terminal multiplixer Documentation=man:tmux(1)

+

After=gpg-agent.service

+

Wants=gpg-agent.service

+

+

[Service]

+

Type=forking

+

ExecStart=/usr/bin/tmux start

+

ExecStop=/usr/bin/tmux kill-server

+

Environment=DISPLAY=:0

+

EnvironmentFile=/tmp/gpg-agent-info

+

+

[Install]

+

WantedBy=multiplexer.target

+

}}

+

+

Once this is done, {{ic|systemctl --user enable}} {{ic|tmux.service}}, {{ic|multiplexer.target}} and any services you created to be run by {{ic|cruft.target}} and you should be set to go! Activated {{ic|user-session@.service}} as described above, but be sure to remove the {{ic|1=Conflicts=getty@tty1.service}} from {{ic|user-session@.service}}, since your user session will not be taking over a TTY. Congratulations! You have a running terminal multiplexer and some other useful programs ready to start at boot!

+

+

===== Starting X =====

+

+

You've probably noticed that, since the terminal multiplexer is now {{ic|default.target}}, X will not start automatically at boot. To start X, procede as above, but do not activate or manually link to {{ic|default.target}} {{ic|wm.target}}. Instead, assuming you're booting to a terminal, we'll simply be using a hackish workaround and masking {{ic|/usr/bin/startx}} with a shell alias:

+

+

{{bc|1=alias startx='systemctl --user start wm.target'}}

== User Services ==

== User Services ==

Line 154:

Line 230:

As detailed in {{ic|man systemd.unit}}, the {{ic|%h}} variable is replaced by the home directory of the user running the service. There are other variables that can be taken into account in the [[systemd]] manpages.

As detailed in {{ic|man systemd.unit}}, the {{ic|%h}} variable is replaced by the home directory of the user running the service. There are other variables that can be taken into account in the [[systemd]] manpages.

+

+

=== Note about X applications ===

+

+

Most X apps, need a {{ic|DISPLAY}} variable to run (so it's likely the first reason why your service files aren't starting), so you have to make sure to include it:

+

+

{{hc|$HOME/.config/systemd/user/parcellite.service|<nowiki>

+

[Unit]

+

Description=Parcellite clipboard manager

+

+

[Service]

+

ExecStart=/usr/bin/parcellite

+

Environment=DISPLAY=:0 # <= !

+

+

[Install]

+

WantedBy=mystuff.target

+

</nowiki>}}

+

+

A cleaner way though, it's '''not''' hard code the DISPLAY environment variable (specially if you run more than on display):

Revision as of 16:24, 7 April 2013

systemd offers users the ability to run an instance of systemd to manage their session and services. This allows users to start, stop, enable, and disable units found within certain directories when systemd is run by the user. This is convenient for daemons and other services that are commonly run as a user other than root or a special user, such as mpd.

Setup

startx

Users should first set up systemd-logind to manage their session. If systemd is running as the system init daemon, then this is already happening.

Next, the user must launch systemd by putting the following in their ~/.xinitrc.

systemd --user

If the user is not launching the window manager through systemd --user, then

systemd --user &

should be used and launched like anything else in ~/.xinitrc, before execing the window manager.

After starting X, the user can check whether their session is now being managed by systemd-logind with the following command:

$ loginctl --no-pager show-session $XDG_SESSION_ID | grep Active

If this command prints Active=yes, then the user is now using systemd-logind to manage their session. The user should remove any instances of ck-launch-session or dbus-launch from their ~/.xinitrc, as those commands are unneeded.

Display Managers

All of the major display managers are now using systemd-logind by default, so the loginctl command from the previous section should work as stated. A user simply has to add systemd --user as a program to be started by their desktop environment.

GNOME 3 (using GDM)

For users who wish to have GDM/GNOME 3 auto-start their systemd --user session upon login, they just need to add a special log in session for this:

Make sure to choose the systemd session option at the GDM login screen.

Note: This has only been tested with a pure GDM and GNOME 3 setup. For other set ups, YYMV. This method does not need the systemd user-session scripts installed.

Using systemd --user To Manage Your Session

Systemd has many amazing features, one of which is the ability to track programs using cgroups (by running systemctl status). While awesome for a pid 1 process to do, it is also extremely useful for users, and having it set up and initialize user programs, all the while tracking what is in each cgroup is even more amazing.

All of your systemd user units will go to $HOME/.config/systemd/user. These units take precedence over units in other systemd unit directories.

Note: The [Install] section includes a 'WantedBy' part. When using systemctl --user enable it will link this as $HOME/.config/systemd/user/wm.target.wants/i3.service, allowing it to be started at login. Is recommended enabling this service, not linking it manually.

You can fill your user unit directory with a plethora of services, including ones for mpd, gpg-agent, offlineimap, parcellite, pulse, tmux, urxvtd, xbindkeys and xmodmap to name a few.

Auto-login

If you want to have systemd automatically log you in on boot, then you can use the unit in user-session-units to do so. Enabling a screen locker for will stop someone from booting your computer into a nice, logged in session.

If you installed user-session-units as listed above, then you must copy /usr/lib/systemd/system/user-session@.service to /etc/systemd/system/user-session@yourloginname.service) and edit these lines:

Because user-session@.service starts on tty1, you will need to add Conflicts=getty@tty1.service to the service file, if it doesn't exist already.

Once this is done, systemctl --user enableYOUR_WM.service

One of the most important things you can add to the service files you will be writing is the use of Before= and After= in the [Unit] section. These two parts will determine the order things are started. Say you have a graphical application you want to start on boot, you would put After=xorg.target into your unit. Say you start ncmpcpp, which requires mpd to start, you can put After=mpd.service into your ncmpcpp unit. You will eventually figure out exactly how this needs to go either from experience or from reading the systemd manual pages. Starting with systemd.unit(5) is a good idea.

Other use cases

Persistent terminal multiplexer

You may wish your user session to default to running a terminal multiplexer, such as GNU Screen or Tmux, in the background rather than logging you in to a window manager session. Separating login from X login is most likely only useful for those who boot to a TTY instead of to a display manager (in which case you can simply bundle everything you start in with myStuff.target).

To create this type of user session, procede as above, but instead of creating wm.target, create multiplexer.target:

cruft.target, like mystuff.target above, should start anything you think should run before tmux or screen starts (or which you want started at boot regardless of timing), such as a GnuPG daemon session.

You then need to create a service for your multiplexer session. Here's a sample service, using tmux as an example and sourcing a gpg-agent session which wrote its information to /tmp/gpg-agent-info. This sample session, when you start X, will also be able to run X programs, since DISPLAY is set.

Once this is done, systemctl --user enabletmux.service, multiplexer.target and any services you created to be run by cruft.target and you should be set to go! Activated user-session@.service as described above, but be sure to remove the Conflicts=getty@tty1.service from user-session@.service, since your user session will not be taking over a TTY. Congratulations! You have a running terminal multiplexer and some other useful programs ready to start at boot!

Starting X

You've probably noticed that, since the terminal multiplexer is now default.target, X will not start automatically at boot. To start X, procede as above, but do not activate or manually link to default.targetwm.target. Instead, assuming you're booting to a terminal, we'll simply be using a hackish workaround and masking /usr/bin/startx with a shell alias:

alias startx='systemctl --user start wm.target'

User Services

Users may now interact with units located in the following directories just as they would with system services (ordered by ascending precedence):

/usr/lib/systemd/user/

/etc/systemd/user/

~/.config/systemd/user/

To control the systemd instance, the user must use the command systemctl --user.

Installed by packages

A unit installed by a package that is meant to be run by a systemd user instance should install the unit to /usr/lib/systemd/user/. The system adminstration can then modify the unit by copying it to /etc/systemd/user/. A user can then modify the unit by copying it to ~/.config/systemd/user/.