Systemd

Systemd

From The Chakra Project

Jump to: navigation, search

Contents

Utilities-terminal.pngsystemd
a system initialization, service and session manager (only) for Linux, replacing the System V init daemon.

For a time it seemed that Canonicals Upstart would replace the dated Sysvinit but instead systemd increasingly gained popularity among Linux distributions.

One distinctive feature of systemd is, that it allows to start services concurrently at system boot without the need to explicitly specify their dependencies in advance. As a result, the system starts quicker.

Systemd also handles various tasks that were previously carried out using distribution-specific scripts; as a side effect, this eliminates various user interface and configuration differences between distributions.


Warning: systemd does not support /usr on a separate partition. You will not be able to boot without libdbus accessible on the root partition.

Using systemd

The systemd administration interface consist of multiple commands, each responsible for a well-defined subset of tasks.

systemctl
query and control the state of the system and systemd service manager
journalctl
query the journal instead of the log files in older init systems.
systemd-cgls
recursively shows the contents of the selected Linux control group hierarchy in a tree
systemadm
a graphical frontend for the systemd system and service manager that allows introspection and control of systemd.

System & Service Control (systemctl)

Service Overview

By simply typing

$ systemctl

in your shell, you can query the state of all services that were started during boot or runtime. For example

kdm.service    loaded  active      running        K Display Manager

is running just fine, while

ntpd.service   loaded  maintenance maintenance    Network Time Service

informs you about a service that failed to run or otherwise encountered a problem.

Service Details

$systemctl status <service>

shows you the exact status of <service>, including its runtime condition or the exit-status in case of a malfunction, for example:.

ntpd.service - Network Time Service
         Loaded: loaded (/etc/systemd/system/ntpd.service)
         Active: maintenance
         Main: 953 (code=exited, status=255)
         CGroup: name=systemd:/systemd-1/ntpd.service

Controlling Services

Systemctl provides a couple of commands to control (start, stop, etc.) the available services (like httpd or mysqld for example).

list-units
The available services or units can be seen in /usr/lib/systemd/system and /etc/systemd/system (the latter takes precedence).
start <service>
Activates a service immediately
stop <service>
Deactivates a service immediately
restart <service>
Restarts a service
reload <service>
Reloads a service
status <service>
Shows status of a service including whether it is running or not:
enable <service>
Enables a service to be started on bootup
disable <service>
Disables a service to not start during bootup

If you want to start your Apache server for example, you'd type:

$ systemctl start httpd

Power Management

reboot
Shut down and reboot the system
poweroff
Shut down and power-off the system:
suspend
Suspend the system:
hibernate
Put the system into hibernation:
hybrid-sleep
Put the system into hybrid-sleep state (or suspend-to-both):

For example, to reboot the system:

$ systemctl reboot

System Logs (journalctl)

Instead of the many text log files being used before systemd, reading logs is now invoked by simply typing:

# journalctl

... for a specific running service

# journalctl _SYSTEMD_UNIT=systemd-logind.service

... from a specific executable

# journalctl /usr/lib/systemd/systemd

... for a specific timeframe

Two options can be used to narrow down the logs to a specific time:

--since=DATE
Start showing entries newer or of the specified date
--until=DATE
Stop showing entries older or of the specified date

where DATE is in the form YYYY-MM-DD_hh:mm:ss. The time is optional, only the date is needed.

... for a specific priority

Only prints out messages of a specified priority level or range The option takes either a single numeric or textual log level between 0 and 7, ordered in descending severity.

  • 0 || emerg
  • 1 || alert
  • 2 || crit
  • 3 || err
  • 4 || warning
  • 5 || notice
  • 6 || info
  • 7 || debug

An example for a single log level might look like this:

# journalctl -p err

Printing the logs in the range of severity levels between 'emergency' and 'error':

# journalctl -p 0..3

If a single log level is specified, all messages with this log level or a lower (hence more important) log level are shown. If a range is specified, all messages within the range are shown, including both the start and the end value of the range.
That implies that both above examples return the same output.

... since the last boot

# journalctl -b

New commands to filter journalctl are created with every update of systemd. See Journalctl

Using Persistent Logfiles

By default, these logs are volatile, removed on every reboot. From systemd 195 version on, Chakra has made these files persistent (there is a /var/log/journal), and use a maximum of 25MiB disk space. You can adjust these amounts by editing:

File: /etc/systemd/journald.conf
SystemMaxUse=25M

Leaving this an empty value will use the default of 10 % of the root filesystem, for example, a 30 GiB root partition will result in a maximum of 3 GiB used for journal.

Info can be read from the Journal many different ways, to create a text file from the complete journalctl:

# journalctl -a > read_log.txt

Runlevels/targets

Systemd has a concept of targets which serve a similar purpose as runlevels but act a little different. Each target is named instead of numbered and is intended to serve a specific purpose. Some targets are implemented by inheriting all of the services of another target and adding additional services to it. There are systemd targets that mimic the common SystemVinit runlevels so you can still switch targets using the familiar telinit RUNLEVEL command. The runlevels that are assigned a specific purpose on vanilla Fedora installs; 0, 1, 3, 5, and 6; have a 1:1 mapping with a specific systemd target. Unfortunately, there's no good way to do the same for the user-defined runlevels like 2 and 4. If you make use of those it is suggested that you make a new named systemd target as /etc/systemd/system/$YOURTARGET that takes one of the existing runlevels as a base (you can look at /usr/lib/systemd/system/graphical.target as an example), make a directory /etc/systemd/system/$YOURTARGET.wants, and then symlink the additional services that you want to enable into that directory. (The service unit files that you symlink live in /usr/lib/systemd/system).

SystemVinit RunlevelSystemd TargetNotes
0 runlevel0.target, poweroff.target Halt the system.
1, s, single runlevel1.target, rescue.target Single user mode.
2, 4 runlevel2.target, runlevel4.target, multi-user.target User-defined/Site-specific runlevels. By default, identical to 3.
3 runlevel3.target, multi-user.target Multi-user, non-graphical. Users can usually login via multiple consoles or via the network.
5 runlevel5.target, graphical.target Multi-user, graphical. Usually has all the services of runlevel 3 plus a graphical login.
6 runlevel6.target, reboot.target Reboot
emergency emergency.target Emergency shell

Changing runlevels:

SystemVinit CommandSystemd CommandNotes
telinit 3 systemctl isolate multi-user.target (OR systemctl isolate runlevel3.target OR telinit 3) Change to multi-user run level.
sed s/^id:.*:initdefault:/id:3:initdefault:/ ln -sf /usr/lib/systemd/system/multi-user.target /etc/systemd/system/default.target Set to use multi-user runlevel on next reboot.

Running DEs under systemd

To enable graphical login run your preferred Display Manager daemon (e.g. KDM). At the moment service files exist for gdm, kdm and slim, but there isn't one for xdm.

# systemctl enable kdm.service

This should work out of the box. If not, you might have a default.target set manually or from a older install:


# ls -l /etc/systemd/system/default.target
/etc/systemd/system/default.target -> /usr/lib/systemd/system/graphical.target

simply delete the symlink and systemd will use its stock default.target i.e. graphical.target.

# rm /etc/systemd/system/default.target

On KDE start an error message will appear saying "console-kit-daemon.unit" could not be found. To solve this problem install systemd-units.

Chakra GNU/Linux integration

As of October 19 2012, Chakra GNU/Linux has made the full switch to switch to systemd. All old initscripts files are removed, there is no longer an rc.conf.

Native systemd configuration files

  • Add a hostname
File: /etc/hostname
myhostname
  • Console and keymap settings
The /etc/vconsole.conf file configures the virtual console, i.e. keyboard mapping and console font.
File: /etc/vconsole.conf
KEYMAP=us
FONT=lat9w-16
FONT_MAP=8859-1_to_uni
  • OS info
/etc/os-release contains data that is defined by the operating system vendor and should not be changed by the administrator.
File: /etc/os-release
NAME=Chakra GNU/Linux
ID=chakra
PRETTY_NAME=Chakra GNU/Linux
ANSI_COLOR=1;34
  • Locale settings (read man locale.conf for more options)
File: /etc/locale.conf
LANG=en_US.utf8
LC_COLLATE=C
  • Configure kernel modules to load during boot
systemd uses /etc/modules-load.d/ to configure kernel modules to load during boot in a static list. Each configuration file is named in the style of /etc/modules-load.d/<program>.conf. The configuration files should simply contain a list of kernel module names to load, separated by newlines. Empty lines and lines whose first non-whitespace character is # or ; are ignored. Example:
File: /etc/modules-load.d/virtio-net.conf
# Load virtio-net.ko at boot
virtio-net
  • Configure kernel modules blacklist
systemd uses /etc/modprobe.d/ to configure kernel modules blacklist. Each configuration file is named in the style of //etc/modprobe.d/<program>.conf. Empty lines and lines whose first non-whitespace character is # or ; are ignored. Example:
File: /etc/modprobe.d/snd_hda_intel
blacklist snd_hda_intel

or

File: /etc/modprobe.d/snd_hda_intel
install snd_hda_intel /bin/false
  • Describe temporary files
systemd-tmpfiles uses the configuration files in /etc/tmpfiles.d/ to describe the creation, cleaning and removal of volatile and temporary files and directories which usually reside in directories such as /run or /tmp. Each configuration file is named in the style of /etc/tmpfiles.d/<program>.conf.

FAQ

For an up-to-date list of known issues, look at the upstream TODO.

Why are my console fonts ugly?

A: If no font is set in /etc/vconsole.conf, then a standard font will be used. The standard font is chosen due to it supporting a wide range of character sets. Set your preferred font to fix the issue.

Why does my machine hang at reboot?

You're probably using syslog-ng. Use rsyslog instead.

Why do I get log messages on my console?

A: You must set the kernel loglevel yourself. Historically, /etc/rc.sysinit did this for us and set dmesg loglevel to '3', which was a reasonably quiet loglevel. Either add 'loglevel=3' or 'quiet' to your kernel cmdline.

Why are there duplicates in the output of df/mount?

A: Systemd expects /etc/mtab to be a symlink to /proc/self/mounts. This is going to be the recommended setup by upstream (util-linux) in the near future, but for the time being there are still some regressions related to fuse. For that reason we leave /etc/mtab as it is until the last kinks have been worked out upstream. You can manually create the symlink if you think you are not affected by the regressions.

Why does systemd not support the RTC being in localtime?

A: In principle, there is nothing stopping you from adding some unit files that will allow the RTC to be in localtime, but there are a few reasons why we have not (and probably will not) implement it by default:

  • The reason for allowing the RTC to be in localtime was to allow dualboot with Windows (who uses localtime). However, for some time now, Windows has been able to deal with the RTC being in UTC by setting the following registry key
HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\RealTimeIsUniversal

This needs to be a DWORD key with a value of 1.

  • Dealing with daylight saving time is messy. If the DST changes when your computer is off, your clock will be wrong on next boot (there is a lot more to it).
  • Recent kernels set the system time from the RTC directly on boot without using 'hwclock', the kernel will always assume that the RTC is in UTC. This means that if the RTC is in localtime, then the system time will first be set up wrongly and then corrected shortly afterwards on every boot. This is possibly the reason for certain weird bugs (time going backwards is rarely a good thing).

How do I change the current runlevel?

A: In systemd runlevels are exposed via "target units". You can change them like this:

# systemctl isolate runlevel5.target

or

# systemctl isolate runlevel3.target

Note however, that the concept of runlevels is a bit out of date, and it is usually nicer to use modern names for this. e.g.:

# systemctl isolate graphical.target

This will only change the current runlevel, and has no effect on the next boot.

How do I boot into a different "runlevel"?

A: The standard target (which is what runlevels are called in a systemd world) is graphical.target (which roughly corresponds to the old runlevel 5). To change the default target at boot-time, append one of the following kernel parameters to your GRUB kernel line:

  • systemd.unit=multi-user.target (which roughly corresponds to the old runlevel 3),
  • systemd.unit=rescue.target (which roughly corresponds to the old runlevel 1).

How do I change the default runlevel/target to boot into?

A: The symlink /etc/systemd/system/default.target controls where we boot into by default. Link it to the target unit of your choice. For example, like this:

# systemctl -f enable multi-user.target

or

# systemctl -f enable graphical.target

How do I know the current run level?

A: runlevel command still works with systemd. You can continue using that however runlevels is a legacy concept in systemd and is emulated via 'targets' and multiple targets can be active at the same time. So the equivalent in systemd terms is

# systemctl list-units --type=target

How do I make a custom unit file?

A: The unit files in /etc/systemd/system take precedence over the ones in /usr/lib/systemd/system. To make your own version of a unit (which will not be destroyed by an upgrade), copy the old unit file from /lib to /etc and make your changes there.

How do I change the number of gettys running by default?

To add another getty:

Simply place another symlink for instantiating another getty in the getty.target.wants/ directory:

# ln -sf /usr/lib/systemd/system/getty@.service /etc/systemd/system/getty.target.wants/getty@tty9.service # systemctl daemon-reload # systemctl start getty@tty9.service

To remove a getty:

Simply remove the getty symlinks you want to get rid of in the getty.target.wants/ directory:

# rm /etc/systemd/system/getty.target.wants/getty@tty5.service /etc/systemd/system/getty.target.wants/getty@tty6.service # systemctl daemon-reload # systemctl stop getty@tty5.service getty@tty6.service

systemd does not use /etc/inittab file.

How do I get more verbose output during boot?

A: By default systemd does not give much (if any) output during boot. Firstly, lots of output from services running in parallel would be very messy, and secondly, boot is supposed to be so fast that status messages would slow it down.

If you append the kernel parameter "verbose" to your kernel line in GRUB, you will get lots of output during boot. However, this is only really meant as a debugging tool as it is not very useful during normal use. Any messages are logged to the system log and if you want to find out about the status of your system

$ journalctl

and

$ systemctl

are your friends.

What kernel options do I need to enable in case I don't use the official Chakra GNU/Linux kernel?

A: kernels prior to 2.6.36 are unsupported.

This is a partial list of required/recommended options, there might be more:

CONFIG_DEVTMPFS=y
CONFIG_CGROUPS=y
CONFIG_AUTOFS4_FS=[y|m]
CONFIG_IPV6=[y|m], optional, but highly recommended
CONFIG_RTC_DRV_CMOS=y, optional, but highly recommended
CONFIG_FANOTIFY=y, optional, required for systemd readahed. Availabe in Linux kernel >= 2.6.37-rcX.
CONFIG_UEVENT_HELPER_PATH should be empty, if you want to use systemd without initramfs

What other units does a unit depend on?

For example, if you want to figure out which services a target like multi-user.target pulls in, use something like this:

$ systemctl show -p "Wants" multi-user.target
Wants=rc-local.service avahi-daemon.service rpcbind.service NetworkManager.service acpid.service dbus.service atd.service crond.service auditd.service ntpd.service udisks.service bluetooth.service cups.service wpa_supplicant.service getty.target modem-manager.service portreserve.service abrtd.service yum-updatesd.service upowerd.service test-first.service pcscd.service rsyslog.service haldaemon.service remote-fs.target plymouth-quit.service systemd-update-utmp-runlevel.service sendmail.service lvm2-monitor.service cpuspeed.service udev-post.service mdmonitor.service iscsid.service livesys.service livesys-late.service irqbalance.service iscsi.service netfs.service

Instead of "Wants" you might also try "WantedBy", "Requires", "RequiredBy", "Conflicts", "ConflictedBy", "Before", "After" for the respective types of dependencies and their inverse.

Optimization

Less output

Change 'verbose' to 'quiet' on the kernel line in GRUB. For some systems, particularly those with an SSD, the slow performance of the TTY is actually a bottleneck, and so less output means faster booting.

Early start

One central feature of systemd is dbus and socket activation, this causes services to be started when they are first accessed, and is generally a good thing. However, if you know that a service (like polkit) will always be started during boot, then the overall boot time might be reduced by starting it as early as possible. This can be achieved (if the service file is set up for it, which in most cases it is) by issuing:

# systemctl enable polkit.service

This will cause systemd to start polkit as soon as possible, without causing races with the socket or dbus activation.

Automount

The default setup will fsck and mount all filesystems before starting most daemons and services. If you have a large /home partition, it might be better to allow services that do not depend on /home to start while /home is being fsck'ed. This can be acheived by adding the following options to the fstab entry of your /home partition

comment=systemd.automount

This will fsck and mount /home when it is first accessed, and the kernel will buffer all file access to /home until it is ready.

/etc/mtab

systemd requires that /etc/mtab is a symlink to /proc/self/mounts, or the following warning will be printed:

/etc/mtab is not a symlink or not pointing to /proc/self/mounts. This is not supported anymore. Please make sure to replace this file by a symlink to avoid incorrect or misleading mount(8) output.

Replace the file with a symlink with ln:

# ln -fs /proc/self/mounts /etc/mtab

Without doing this, features such as automounting through /etc/fstab will be unavailable.

Warning: If you use FUSE mounts or filesystem specific options such as user or users, it's required to recompile util-linux with --enable-libmount-mount.

Disabling native mount

With v12 or later you can disable the native mount and fsck facility in /etc/systemd/system.conf.

MountAuto=no
SwapAuto=no
Note: These options are enabled by default.

Remote filesystem mounts

If you have NFS mounts listed in /etc/fstab then systemd will attempt to mount them but will typically do so too early, before networking has been configured. To get the timing correct we need to tell systemd explicitly that the mount depends on networking and on rpc.statd. To do this, create a file under /usr/lib/systemd/system named <mount-unit-name>.mount with contents as follows.

[Unit]
Description=<mountpoint>
Wants=network.target statd.service
After=network.target statd.service 

[Mount]
What=<server>:<share>
Where=<mountpoint>
Type=nfs
StandardOutput=syslog
StandardError=syslog

In the above

  • mount-unit-name is the full path to the mountpoint in an escaped format. For example, a mount unit for /usr/local must be named usr-local.mount.
  • mountpoint is the local mountpoint
  • server:share specify the remote filesystem in the same manner as for /etc/fstab

See systemd.unit(5) and systemd.mount(5) for further details.

A similar approach will probably be required for other remote filesystem types such as nfs4 and cifs.

Alternatively, you can mark these entries in /etc/fstab with the option 'comment=systemd.automount'. Make sure that if you also include 'defaults' as a mount option that you override the implicit 'auto' with 'noauto'. This will cause the device to be mounted on first access, similar to Autofs.

Readahead

systemd comes with its own readahead implementation, this should in principle improve boot time. However, depending on your kernel version and the type of your hard drive, your milage might vary (i.e. it might be slower). To enable do:

# systemctl enable systemd-readahead-collect.service # systemctl enable systemd-readahead-replay.service

Remember that in order for the readahead to work its magic you should reboot a couple of times.

User sessions

systemd can divide user sessions into cgroups. Add "session optional pam_systemd.so" to your relevant /etc/pam.d files (e.g., login for tty logins, sshd for remote access, kde for password kdm logins, kde-np for automatic kdm logins).

Before:

$ systemd-cgls systemd:/system/getty@.service

After:

$ systemd-cgls systemd:/user/example/


See also

Official Sites:

Tutorials:

Other Wikis: