systemd

From Gentoo Wiki
Jump to: navigation, search

External resources

systemd is a modern sysvinit & RC replacement for Linux systems. It is supported in Gentoo as an alternate init system.

Pre-installation Configuration

Note
If you're updating from <=sys-apps/systemd-203 check the upgrade subpage.

Kernel

systemd makes use of many modern Linux kernel features. Right now, the lower bound on kernel version is set in the ebuild to 2.6.39. In recent versions of sys-kernel/gentoo-sources, there is a convenient way of selecting the mandatory and optional kernel options for systemd:

KERNEL Quick setup using gentoo-sources
Gentoo Linux --->
        Support for init systems, system and service managers --->
                [*] systemd

If you wish to configure your Kernel options manually, or do not use sys-kernel/gentoo-sources, the following kernel configuration options are required and recommended:

KERNEL Mandatory options
General setup  --->
	[*] Control Group support
	[*] open by fhandle syscalls
	[ ] Enable deprecated sysfs features to support old userspace tools
	[*] Configure standard kernel features (expert users)  --->
		[*] Enable eventpoll support
		[*] Enable signalfd() system call
		[*] Enable timerfd() system call
[*] Networking support --->
Device Drivers  --->
	Generic Driver Options  --->
		[*] Maintain a devtmpfs filesystem to mount at /dev
File systems  --->
	[*] Inotify support for userspace
	Pseudo filesystems  --->
		[*] /proc file system support
		[*] sysfs file system support
KERNEL Recommended options
General setup  --->
	[*] Namespaces support  --->
		[*] Network namespace
[*] Enable the block layer  --->
	[*] Block layer SG support v4
Processor type and features  --->
	[*] Enable seccomp to safely compute untrusted bytecode
Networking support --->
	Networking options --->
		<*> The IPv6 protocol
Device Drivers  --->
	Generic Driver Options  --->
		()  path to uevent helper
		[ ] Fallback user-helper invocation for firmware loading
Firmware Drivers  --->
	[*] Export DMI identification via sysfs to userspace
File systems --->
	<*> Kernel automounter version 4 support (also supports v3)
	Pseudo filesystems --->
		[*] Tmpfs virtual memory file system support (former shm fs)
		[*]   Tmpfs POSIX Access Control Lists
		[*]   Tmpfs extended attributes

For UEFI system you'll also need to enable the following:

KERNEL UEFI support
[*] Enable the block layer  --->
	Partition Types  --->
		[*] Advanced partition selection
		[*]   EFI GUID Partition support
Processor type and features  --->
	[*] EFI runtime service support
Firmware Drivers  --->
        EFI (Extensible Firmware Interface) Support -->
	        <*> EFI Variable Support via sysfs

In the case you are using BFQ scheduler, it's recommended by BFQ upstream to enable "BFQ hierarchical scheduling support" under "Enable the block layer -> IO Schedulers"

For an up-to-date list, see section "REQUIREMENTS" in the upstream README file.

The /run directory

The /run directory is used by systemd and other applications as a non-persistent storage for runtime data like pid files, sockets and state files.

The systemd package will create /run directory itself. However, please note that this change will trigger automatic mounting of it in OpenRC as well, and may trigger using it by different software packages.

/etc/mtab

Upstream only supports /etc/mtab file being a symlink to /proc/self/mounts. Also not creating this symlink will cause problems with mount (bug #434090) and df (bug #477240). In the past some utilities wrote information (like mount options) into /etc/mtab and thus it was supposed to be file. Currently all software is supposed to avoid this problem but before you do switch check bug #477498 to be sure that you are not affected by any regressions.

To create the symlink, run:

root #ln -sf /proc/self/mounts /etc/mtab

Ensure /usr is present at boot time

For a split /usr configuration, one must use an initramfs to mount /usr before starting systemd. See the Official Initramfs Gentoo Guide for instructions.

Using LVM2 and Initramfs

When sys-fs/lvm2 is used and the system is booted using an initramfs, the initramfs will have to be created using sys-kernel/genkernel or sys-kernel/genkernel-next by running:

root #genkernel --udev --lvm <target>
<target> is initramfs or one of the other genkernel targets which imply the creation of an initramfs. See:
user $genkernel --help

When LVM is used, the lvmetad daemon needs to be started as well. Otherwise systemd will be unable to mount LVM volumes. lvmetad can be enabled in /etc/lvm/lvm.conf:

FILE /etc/lvm/lvm.conf Snippet of required changes in lvm.conf
# Set use_lvmetad to '1' for systemd
use_lvmetad = 1
Note
Instead of modifying /etc/lvm/lvm.conf this could probably be achieved through a lvmetad.socket unit which activates a lvmetad.service, but current versions of sys-fs/lvm2 don't ship those yet.

Installation

sys-apps/systemd contains udev and, then, you can safely let sys-fs/udev be removed as systemd will be the provider for virtual/udev.

  • Enable the systemd USE flag globally (make.conf). The consolekit USE flag should also be disabled to prevent conflicts with the systemd-logind service. You can also switch to a systemd subprofile to use saner USE flags defaults not needing to change make.conf:
root #eselect profile list

Then update your world with the new flags:

root #emerge -avDN @world

If you get dependency problems (sys-fs/udev is blocking sys-apps/systemd), sys-fs/udev may be in the world file. Try to resolve this by:

root #emerge --deselect sys-fs/udev

Booting with systemd

In order to run systemd, you have to switch the init that your executable kernel (or your initramfs) uses.

Warning
The services that you have set up in your previous service manager will not be automatically started, this is because you are switching to a different service manager; it order to obtain back functionality like for example the networking or a login manager, you will need to enable and start these services again. More information about this follows in the services section later in this article.
Note
In case your migration yields a broken state, you can always opt to boot back into the default service manager (OpenRC) by undoing this init change step; allowing you to use the troubleshooting section at the end of this article to fix the problem.

The following subsections document how to switch the init in one of the boot managers or the kernel.

Grub Legacy (0.x)

The init=/usr/lib/systemd/systemd argument should be added to the kernel command-line. An example excerpt from grub.conf would look like:

FILE /boot/grub/grub.conf Example GRUB config for systemd
title=Gentoo with systemd
root (hd0,0)
kernel /vmlinuz root=/dev/sda2 init=/usr/lib/systemd/systemd

Should the system boot using openrc, try using real_init instead of init

Grub 2

If using the grub2-mkconfig configuration generator, add the init option to GRUB_CMDLINE_LINUX (it is not required if using initramfs generated by dracut with systemd inside).

FILE /etc/default/grub Example grub2-mkconfig config for systemd
# Append parameters to the linux kernel command line
GRUB_CMDLINE_LINUX="init=/usr/lib/systemd/systemd"

If writing a configuration by hand (experts only), append the init parameter to the linux or linux16 command.

FILE /boot/grub/grub.cfg Example GRUB2 configuration fragment
linux /vmlinuz-3.10.9 root=UUID=508868e4-54c6-4e6b-84b0-b3b28b1656b6 init=/usr/lib/systemd/systemd

If using genkernel-next's initrd, use real_init instead of init.

In kernel config

You can also set this in your kernel configuration. See "Processor type and features" -> "Built-in kernel command line". Note that this technique works for both grub and grub2.

Setting root password

At this point you might also want to set your root password. If something goes wrong, systemd would prompt for root password to go into maintenance mode.

Post Installation Configuration

systemd supports a few system configuration files to set the most basic system details.

Note
While some system configuration parameters can be updated by modifying the appropriate configuration files, most settings are managed using utilities that require systemd to be running. In this case, it is safe to reboot your computer with systemd and use the hostnamectl, localectl and timedatectl utilities as required.

Hostname

To set the hostname, create/edit /etc/hostname and simply provide the desired hostname.

When booted using systemd, a tool called hostnamectl exists for editing /etc/hostname and /etc/machine-info. To change hostname, run:

root #hostnamectl set-hostname <HOSTNAME>

Refer to man hostnamectl for more options.

Locale

Usually, you will get your locale properly migrated from openRC when installing systemd. If required, you can set the locale in /etc/locale.conf as per the Handbook instructions:

FILE /etc/locale.conf System locale configuration
LANG="en_US.utf8"

Once booted with systemd, the tool localectl is used to set locale and console or X11 keymaps. To change the system locale, run the following command.

root #localectl set-locale LANG=<LOCALE>

To change the virtual console keymap:

root #localectl set-keymap <KEYMAP>

And finally, to set the X11 layout:

root #localectl set-x11-keymap <LAYOUT>

If needed you can specify the model, variant and options too:

root #localectl set-x11-keymap <LAYOUT> <MODEL> <VARIANT> <OPTIONS>

Time & Date

Time and date can be set using the timedatectl utility. Managing the system time before booting with systemd is complex, so it is recommended to leave this until after booting and using the timedatectl utility. It is recommended for systemd-timedated.service to set a symlink from your timezone "/usr/share/zoneinfo/[timezone]" to "/etc/localtime". The ntpdate.service is deprecated and not useable anymore with networkmanger and systemd.

Automatic module loading

Automatic module loading is configured in a different file, or rather directory of files. The configuration files are stored in /etc/modules-load.d. On boot every file with a list of modules will be loaded. The file format is a list of modules seperated by newline and can have any name you want as long as it ends with .conf. You can separate out the module loading by program, service or whatever way you like. My virtualbox.conf example is listed below. But I can imagine one also has an iptables.conf for all the kernel modules needed for your firewall or one big file with all modules.

FILE /etc/modules-load.d/virtualbox.conf Example file for the virtualbox modules
vboxdrv
vboxnetflt
vboxnetadp
vboxpci

Handling of log files

systemd has its own way of handling log files without needing to rely on any external log system (like syslog-ng or rsyslog). Messages can now be read with journalctl. Anyway, you can still configure it to use your preferred external tool for handling them. Please type man journald.conf for learning about how to configure journald to suit your needs.

/tmp is now in tmpfs

Unless you explicitly mount some other filesystem to /tmp in your fstab, systemd will mount /tmp as tmpfs. That means it will be emptied on every boot and its size will be limited to 50% of your RAM size. To know why this is the desired behavior and how to modify it, take a look at API File Systems

Configure verbosity of boot process

When migrating to systemd you will probably notice differences regarding verbosity of boot process:

  • quiet option not only affects to kernel output, but also to systemd itself. Then, while you are setting up systemd for your machine, you will probably want to drop it to see any errors could arise more easily. After that, you can add it back to get a quiet (and faster) boot.
  • Even passing quiet option, you can still configure systemd to show its status by also passing systemd.show_status=1.
  • When not using quiet option, you could get some messages overwriting consoles, that is caused by kernel configuration (see man 5 proc and look for /proc/sys/kernel/printk). To tweak it you can pass the loglevel=5 boot parameter to the kernel (or a lower value like 1).

Services

At some point you will have to reboot your system in order to get systemd running (in system mode). Be sure to read all of this document to ensure you have systemd configured as completely as possible before rebooting. Note that journalctl(8) works with systemd(8) not running, but that systemctl(8) will not do anything useful without systemd running. You will likely want to complete the service configuration (enabling and starting of services) after you get logged in to your system running systemd.

OpenRC services

Although systemd originally intended to support running old init.d scripts, that support is not suited well for a dependency-based RC like OpenRC and thus is completely disabled on Gentoo. OpenRC provides additional measures to ensure that init.d scripts can't be run when OpenRC was not used to boot the system (otherwise the results would be unpredictable).

Listing available services

All available service units can be listed using the list-units verb provided by systemctl:

root #systemctl list-units
UNIT                               LOAD   ACTIVE SUB       DESCRIPTION
boot.automount                     loaded active waiting   EFI System Partition Automount
proc-sys-fs-binfmt_misc.automount  loaded active waiting   Arbitrary Executable File Formats File System Automount Point
-.mount                            loaded active mounted   /
boot.mount                         loaded active mounted   /boot
dev-mqueue.mount                   loaded active mounted   POSIX Message Queue File System
run-user-1000.mount                loaded active mounted   /run/user/1000
tmp.mount                          loaded active mounted   Temporary Directory
systemd-ask-password-console.path  loaded active waiting   Dispatch Password Requests to Console Directory Watch
systemd-ask-password-wall.path     loaded active waiting   Forward Password Requests to Wall Directory Watch
avahi-daemon.service               loaded active running   Avahi mDNS/DNS-SD Stack
bluetooth.service                  loaded active running   Bluetooth service
cups-browsed.service               loaded active running   Make remote CUPS printers available locally
cups.service                       loaded active running   CUPS Printing Service
dbus.service                       loaded active running   D-Bus System Message Bus
docker.service                     loaded active running   Docker Application Container Engine
gentoo-local-misc.service          loaded active exited    Service for local.d/misc.*
getty@tty2.service                 loaded active running   Getty on tty2
getty@tty3.service                 loaded active running   Getty on tty3
getty@tty4.service                 loaded active running   Getty on tty4
kmod-static-nodes.service          loaded active exited    Create list of required static device nodes for the current kernel
mysqld.service                     loaded active running   MySQL database server
NetworkManager.service             loaded active running   Network Manager
...

The following file suffixes are of interest:

  • .service - plain service files (e.g. ones just running a daemon directly),
  • .socket - socket listeners (much like inetd),
  • .path - filesystem triggers for services (running services when files change etc.).

Alternatively, systemctl tool can be used to list all services (including implicit ones):

root #systemctl --all --full

And finally the systemadm graphical tool can be used. It can be installed with the sys-apps/systemd-ui package.

Installing custom unit files

Custom unit files can be placed in /etc/systemd/system, where they'll be recognized after running:

root #systemctl daemon-reload

/usr/lib/systemd/system is reserved for service files installed by the package manager.

Customizing unit files

When only minor changes to a unit are needed, there's no need to create a full copy of the original unit file in /etc/systemd/system Overriding settings in a package management provided unit can be achieved by drop-in files in a *.d directory named after the original unit (e.g. apache2.d) in /etc/systemd/system/.

FILE /etc/systemd/system/apache2.d/mem-limit.conf Example of adding/overriding settings in a service file
[Service]
MemoryLimit=1G

A reload of systemd is needed to inform it of the changes:

root #systemctl daemon-reload

Then the service needs to be restarted to apply the changes:

root #systemctl restart apache2

Verify, the changed property was applied to the service:

root #systemctl show --property=MemoryLimit apache2
MemoryLimit=1074000000

Enabling, disabling, starting and stopping services

The usual way of enabling a service is using

root #systemctl enable foo.service

Services can be disabled likewise:

root #systemctl disable foo.service

These commands enable services using their default name in default target (both specified in Install section of the service file). However, sometimes services either don't provide that information or you want to use another name/target.

Note that these commands only enable or disable the system to be started on a next boot; if you want to start the service right now, you can use

root #systemctl start foo.service

Services can be stopped likewise:

root #systemctl stop foo.service

Enabling a service under a custom name

When the name provided by Alias in the unit's [Install] section does not meet the expectations and providing a permanent new value for this through a customization is not desired, a symlink can be created manually in /etc/systemd/system/*.wants/. The name of the *.wants directory can either specify a target or another service which will depend on the new one.

For example, to install mysqld.service as db.service in the multi-user.target:

root #ln -s /usr/lib/systemd/system/mysqld.service /etc/systemd/system/multi-user.target.wants/db.service

To disable the service, just remove the symlink:

root #rm /etc/systemd/system/multi-user.target.wants/db.service

Native services

Some of Gentoo packages already install systemd unit files. For these services, it is enough to enable them. A quick summary of packages installing unit files can be seen on systemd eclass users list.

The following table lists systemd services matching OpenRC ones:

Migration chart
Gentoo package OpenRC service systemd unit Notes
sys-apps/openrc bootmisc systemd-tmpfiles-setup.service always enabled, uses tmpfiles.d
consolefont systemd-vconsole-setup.service always enabled, uses vconsole.conf
devfs
dmesg
fsck fsck*.service pulled in implicitly by mounts
functions.sh See note bug #373219
hostname (builtin) /etc/hostname
hwclock See note always enabled as part of systemd (ie It is baked in and is not a unit)
keymaps systemd-vconsole-setup.service always enabled, uses vconsole.conf
killprocs
local
localmount local-fs.target actual units are created implicitly from fstab
modules systemd-modules-load.service always enabled, uses /etc/modules-load.d/*.conf
mount-ro
mtab
netmount remote-fs.target
numlock
procfs (builtin)
root remount-rootfs.service
savecache n/a OpenRC internals
staticroute
swap swap.target actual units are created implicitly from fstab
swclock
sysctl systemd-sysctl.service sysctl.conf and sysctl.d/
sysfs (builtin)
termencoding systemd-vconsole-setup.service always enabled, uses vconsole.conf
urandom systemd-random-seed-load.service
systemd-random-seed-save.service
app-admin/rsyslog rsyslog rsyslog.service
app-admin/syslog-ng syslog-ng syslog-ng.service
media-sound/alsa-utils alsasound alsa-store.service (enabled by default)
alsa-restore.socket (enabled by default)
net-misc/dhcpcd dhcpcd dhcpcd.service
net-misc/netifrc net.* netctl@.service net-misc/netctl is originally an Arch Linux tool.
NetworkManager.service For <networkmanager-0.9.8.4 : enable NetworkManager-dispatcher.service for dispatcher.d scripts to work.
Enable NetworkManager-wait-online.service to detect that the system has a working internet connection.
Disable all other managers (e.g., wicd, dhcpcd) and wpa_supplicant.
dhcpcd.service Provided by net-misc/dhcpcd
systemd.networkd.service Part of systemd
net-misc/openntpd ntpd ntpd.service
net-misc/openssh sshd sshd.service runs sshd as a daemon
sshd.socket runs sshd on a inetd-like basis (for each incoming connection)
net-misc/wpa_supplicant wpa-supplicant wpa_supplicant.service D-Bus controlled daemon (e.g. for NetworkManager)
wpa_supplicant@.service interface-specific wpa_supplicant (used like wpa_supplicant@wlan0.service)
net-print/cups cupsd cups.service classic on-boot start up service
cups.socket socket and path activation (cups only started on-demand)
cups.path
net-wireless/bluez bluetooth bluetooth.service
sys-apps/dbus dbus dbus.service
dbus.socket
sys-apps/irqbalance irqbalance irqbalance.service supports daemon mode only
sys-apps/microcode-ctl microcode_ctl Configure microcode as a module to let it load the microcode itself. Go to "Processor type and features" -> "CPU microcode loading support" and remember to add the option you need depending on you having intel or amd processor.
sys-fs/udev udev udev.service
udev-mount (builtin) /dev is mounted as tmpfs
udev-postmount udev-trigger.service
udev-settle.service
sys-power/acpid acpid acpid.service Most of its functionality is done by systemd itself, then, maybe you could consider to stop enabling this
x11-apps/xdm (xdm) xdm.service OpenRC uses common xdm init.d installed by x11-base/xorg-server. With systemd you will need to enable corresponding unit file for each DM (gdm.service, kdm.service...)

Timer services

Since version 197 systemd supports timers, making cron unnecessary on a systemd system. Since version 212 persistent services are supported, replacing even anacron. Persistent timers are run at the next opportunity if the system was powered down when the timer was scheduled.

The following is an example on how to make a simple timer that runs in the context of your user. It will even run if the user is not logged in. Every timed service needs a timer and a service file that is activated by the timer as follows:

FILE ~/.local/share/systemd/user/backup-work.timer Example of a timer running every working day
[Unit]
Description=daily backup work
RefuseManualStart=no
RefuseManualStop=no
 
[Timer]
Persistent=false
OnCalendar=Mon-Fri *-*-* 11:30:00
Unit=backup-work.service
 
[Install]
WantedBy=default.target
FILE ~/.local/share/systemd/user/backup-work.service Example of a service triggering backup
[Unit]
Description=daily backup work
RefuseManualStart=no
RefuseManualStop=yes
 
[Service]
Type=oneshot
ExecStart=/home/<user>/scripts/backup-work.sh

Firstly, you must tell systemd to rescan the service files

user $systemctl --user daemon-reload

You can trigger the backup manually by running

user $systemctl --user start backup-work.service

You can start and stop the timer manually by running

user $systemctl --user start backup-work.timer
user $systemctl --user stop backup-work.timer

And finally to activate the timer at every system start run

user $systemctl --user enable backup-work.timer

You can check the last result of running the service with

user $systemctl --user list-timers

Emailing failures

If a timed service runs and fails you can be informed by email. This is possible with the OnFailure stanza that allows you to specify what should happen if a service fails. A failure is detected by a non-zero return code of the backup-work script. For that change the script as follows:

FILE ~/.local/share/systemd/user/backup-work.service Example of a service triggering backup
[Unit]
Description=daily backup work
RefuseManualStart=no
RefuseManualStop=yes
OnFailure=failure-email@%i.service
 
[Service]
Type=oneshot
ExecStart=/home/<user>/scripts/backup-work.sh

This requires you to have the service failure-email@.service installed, which can be found here.

Replacing cron

The above timer and service files can also be added to /usr/lib/systemd/system to make them available system-wide. The install section should then say WantedBy=multi-user.target to enable the service at system start.

However, cron also runs the scripts in /etc/cron.daily etc. and several packages place scripts there that they expect to be run daily. You can emulate this behaviour with systemd by first installing sys-process/cronbase and then systemd-cron. Just run ./configure --enable-persistent and make. You can ignore the systemd-crontab-generator stuff if you are only interested in running the files in /etc/cron.daily. Just copy the files from systemd-cron/out/build/units to /usr/lib/systemd/system. Then ensure you adjust the path to run-parts in the service files. The run-parts script is located in gentoo in /usr/bin/run-parts. Then activate your new cron replacement with

root #systemctl enable cron.target
root #systemctl start cron.target

Troubleshooting

lvm

If you are switching from openrc to systemd and you need lvm to properly mount your volumes, you should activate lvm service:

root #systemctl enable lvm2-monitor.service

While it might not be needed for activation of root volume, if lvm is integrated into your initramfs, it might not work for other lvm volumes, unless you activate the service.

systemd-bootchart

KERNEL
systemd-bootchart support

As systemd-bootchart attempts to start /sbin/init, you may have to edit its configuration file:

FILE /etc/systemd/bootchart.conf
...
Init=/usr/lib/systemd/systemd
...

Result is a report in svg located in /run/log/.

syslog-ng conflicts with systemd

systemd creates /dev/log as datagram socket [1] [2] so you will need to tell syslog-ng to read from a unix-dgram instead of a unix-stream if you are hitting problems and are using "wrong" stream:

FILE /etc/syslog-ng/syslog-ng.conf
unix-stream('/dev/log');

should be replaced with:

FILE /etc/syslog-ng/syslog-ng.conf
unix-dgram('/dev/log');
in order to use the syslog-ng service in systemd.

sys-fs/cryptsetup configuration

systemd doesn't seem to respect /etc/conf.d/dmcrypt (bug #429966) and, then, you will need to configure it in /etc/crypttab file:

FILE /etc/crypttab Configuration file for encrypted block devices
crypt-home UUID=c25dd0f3-ecdd-420e-99a8-0ff2eaf3f391 -

Check for units that failed to start

To check for units that failed to start you can run:

root #systemctl --failed

Enable Debug Mode

To get more informations you need to set the following in /etc/systemd/system.conf:

FILE /etc/systemd/system.conf
LogLevel=debug

Or enable the debug-shell, that opens an terminal at tty9. This help to debug such service during boot process.

root #systemctl enable debug-shell.service

e4rat usage

Please remember to edit /etc/e4rat.conf setting 'init' to /usr/lib/systemd/systemd, otherwise it will keep booting openrc.

Multi-PV VGs in LVM on LUKS configuration

If you have this configuration:

sdX -> LUKS -> PV1 -> VG1 -> LV1(root) -> /
sdY -> LUKS -> PV2 \
                    |-> VG2 -> LV2 -> /home/SOME_FOLDER
sdZ -> LUKS -> PV3 /

You may experience very slow boot-up and a couple of errors/timeouts from lvm2 systemd services (they are auto-generated by sys-fs/lvm2 when global/use_lvmetad=0 in lvm.conf). They are caused by a timeout of lvm2-activation-early.service.
You may fix this by masking the service like this:

root #systemctl mask lvm2-activation-early.service

You may need to mask the lvm2-activation-net.service too:

root #systemctl mask lvm2-activation-net.service
Note
This fix is tested and valid for: sys-apps/systemd-208-r3 and sys-fs/lvm2-2.02.105-r2. It may be fixed in future LVM or Systemd versions.
Warning
Do not mask the lvm2-activation-early.service if your configuration has LUKS on LVM (i.e. sdX -> LVM -> LUKS).

GRSecurity hardening

Synopsis: systemd-networkd log error

could not find udev device: Permission denied

The error raises due to systemd-networkd works under non-root user.
You should set kernel option CONFIG_GRKERNSEC_SYSFS_RESTRICT=N.

See Also

External resources

References