Linux Systemd

Systemd is a centralized system and setup manager for the Linux computer operating system, including daemons, libraries and applications, developed by Lennart Poettering. The goal was to provide a better framework to represent the dependencies between system services, to enable parallel startup of services during system initialization, and to reduce the system overhead of the shell, eventually replacing the System V and BSD style init programs that are now commonly used.

Most Linux distributions now use systemd instead of System V.

List of common commands

  • List all loaded units: systemctl list-units
  • View the configuration of the specified unit: systemctl cat [serviceName] (e.g. systemctl cat sshd.service )
  • Modify the configuration of the specified unit: systemctl edit [serviceName] (e.g. systemctl edit sshd.service )
  • Check the operational status of the specified unit: systemctl status [serviceName|pid] (e.g. systemctl status sshd.service )
    • If a unit name is specified, then the runtime status information for the specified units is displayed, along with the most recent log data for those units.
    • If a PID is specified, then the runtime status information of the unit to which the specified PID belongs is displayed, along with the most recent log data for those units.
    • If no units or PIDs are specified, then status information is displayed for the entire system, or, if used with -all, for all loaded units (you can use -t to specify the unit type).
  • Start the specified unit: systemctl start [serviceName] (e.g. systemctl start sshd.service)
    • The specified unit must already be loaded.
  • Restart the specified unit: systemctl restart [serviceName] (e.g. systemctl restart sshd.service )
    • If the specified units are not started, start them directly.
  • Stop the specified unit: systemctl stop [serviceName] (e.g. systemctl stop sshd.service )
  • Enable the specified unit: systemctl enable [serviceName] (e.g. systemctl enable sshd.service )
  • Disable the specified unit: systemctl disable [serviceName] (e.g. systemctl disable sshd.service )
  • Reload the configuration of the specified unit: systemctl reload [serviceName] (e.g. systemctl reload sshd.service )
  • Reload all modified configuration files: systemctl daemon-reload

Boot up

For those software that support Systemd, a configuration file is automatically added to the /usr/lib/systemd/system directory when it is installed.

If you want the software to boot, execute the following command (take sshd.service as an example).

1
sudo systemctl enable sshd.service

The above command is equivalent to adding a symbolic link to the /etc/systemd/system directory, pointing to the sshd.service file in /usr/lib/systemd/system.

This is because at boot time, Systemd only executes the configuration file inside the /etc/systemd/system directory. This also means that if you put the modified configuration file in that directory, you can achieve the effect of overwriting the original configuration.

Unit

Configuration file

For software that does not natively support Systemd, you can write your own configuration file for the purpose of boot-up.

Let’s take the sshd.service configuration file as an example and analyze the Systemd configuration file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# /lib/systemd/system/ssh.service

[Unit]
Description=OpenBSD Secure Shell server
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run

[Service]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/usr/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target
Alias=sshd.service

As you can see there are three sections in this file: [Unit] , [Service] and [Install] .

The configuration items are usually repeatable, but the later configuration items replace the previous ones with the same name. So if you want to zero out a setting, you can zero out the setting by adding a null entry (e.g. After=) at the end of the section where the configuration is located.

[Unit]: Startup Order and Dependencies

This section has the following main configuration items.

  • Description : A short description of the current service
  • Documentation : document location (separated by spaces)
    • This can be a link to a web page, the name of a manpages, or a file path.
  • Before : before which services were started
    • This field does not involve dependencies, it just indicates the start order
  • After : Which services are started after
    • This field does not involve dependencies, it just indicates the order of startup
    • Take the configuration in sshd.service as an example, the service needs to be started after network.target and auditd.service
  • Wants : weakly dependent services
    • If the dependent service is stopped, this service does not need to be stopped
  • Requires : Strongly dependent services
    • This service cannot be started if the dependent service is not started
    • If the dependent service is stopped, this service must also be stopped
  • Conflicts : conflicting services
    • If one of the listed services is already running, then this service cannot be started

[Service]: Startup behavior

This section has the following main configuration items.

  • Type: the type of startup. The default value is simple and the optional values are as follows.
    • simple : Make the item started by the ExecStart item the main process
    • forking : The ExecStart item will be started as fork(), when the parent process will exit and the child process will become the master process
    • oneshot : similar to simple, but only executed once, Systemd will wait for it to finish before starting other services
    • dbus : similar to simple, but will wait for the D-Bus signal before starting
    • notify : similar to simple, it will send a notification signal when it finishes, and then Systemd will start other services.
    • idle : Similar to simple, but will not start the service until all other tasks are executed.
      • One use of this option is to keep the output of the service from being mixed with the output of other services.
      • Another use of this option is to execute programs that only need to be executed once at boot time
  • Environment : Specifies the environment variables
  • EnvironmentFile : Environment variable configuration file, the configuration in the form of key=value inside the file can be obtained with $key in the current file
  • ExecStart : The command to be executed when the service starts
  • ExecReload : The command to be executed when the service is restarted
  • ExecStop : Command to be executed when the service is stopped
  • ExecStartPre : Command executed before the service starts
  • ExecStartPost : Command executed after the service is started
  • ExecStopPost : Command executed after the service is stopped
  • Restart : The restart method after the service exits, the default value is no
    • no : process will not be restarted after exiting
    • on-success : restart when the process exits normally (exit status code is 0)
    • on-failure : restart when the process exits abnormally (exit status code is not 0, terminated by signal, program timeout)
    • on-abnormal : restart when the process is terminated by a signal or program timeout
    • on-abort : restart when a signal is received that is not caught
    • on-watchdog : restart when the process times out
    • always : always restart (regardless of the reason)
    • For daemons, the recommended setting is on-failure. For services that are allowed to exit with errors, you can set it to on-abnormal.
  • RemainAfterExit : Whether to restart after exiting
    • When RemainAfterExit=1 is set, this service will try to start again after all programs belonging to this service have been terminated. This is useful for Type=oneshot services
  • TimeoutSec : The number of seconds to wait for this service to fail to enter the “force end” state when starting or stopping.
  • KillMode : Defines how Systemd stops this service, defaults to control-group.
    • control-group : Shut down all processes in this control group when the service is stopped
    • process : Terminate only the main process when the service is stopped (the command after the ExecStart string)
    • mixed : The main process will receive the SIGTERM signal and the child processes will receive the SIGKILL signal
    • none : no process will be killed, only the stop command of the service will be executed
  • RestartSec : The number of seconds Systemd will wait before restarting the service (default is 100ms)

All startup settings can be preceded by a hyphen ( - ) to indicate “error suppression”, i.e. when an error occurs, it does not affect the execution of other commands. Take sshd.service for example, EnvironmentFile=-/etc/sysconfig/sshd (note the hyphen after the equal sign) in the file means that the /etc/sysconfig/sshd file does not exist and no error will be thrown.

[Install]: Installation behavior

This section has the following main configuration items.

  • WantedBy : Indicates the Target where the service is located
    • Generally, service units are listed under multi-user.target.
  • Also : the unit that needs to be enabled when the service is enabled
  • Alias : Specifies the alias file that links to the unit’s configuration file when creating a soft link

Template example

The getty@.service file is used here as an example to analyze how it is possible to start multiple services using a single configuration file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# /lib/systemd/system/getty@.service
#
#  SPDX-License-Identifier: LGPL-2.1+
#
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Getty on %I
Documentation=man:agetty(8) man:systemd-getty-generator(8)
Documentation=http://0pointer.de/blog/projects/serial-console.html
After=systemd-user-sessions.service plymouth-quit-wait.service getty-pre.target
After=rc-local.service

# If additional gettys are spawned during boot then we should make
# sure that this is synchronized before getty.target, even though
# getty.target didn't actually pull it in.
Before=getty.target
IgnoreOnIsolate=yes

# IgnoreOnIsolate causes issues with sulogin, if someone isolates
# rescue.target or starts rescue.service from multi-user.target or
# graphical.target.
Conflicts=rescue.service
Before=rescue.service

# On systems without virtual consoles, don't start any getty. Note
# that serial gettys are covered by serial-getty@.service, not this
# unit.
ConditionPathExists=/dev/tty0

[Service]
# the VT is cleared by TTYVTDisallocate
# The '-o' option value tells agetty to replace 'login' arguments with an
# option to preserve environment (-p), followed by '--' for safety, and then
# the entered username.
ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear %I $TERM
Type=idle
Restart=always
RestartSec=0
UtmpIdentifier=%I
TTYPath=/dev/%I
TTYReset=yes
TTYVHangup=yes
TTYVTDisallocate=yes
KillMode=process
IgnoreSIGPIPE=no
SendSIGHUP=yes

# Unset locale for the console getty since the console has problems
# displaying some internationalized messages.
UnsetEnvironment=LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION

[Install]
WantedBy=getty.target
DefaultInstance=tty1

Run the systemctl status getty@tty1.service command and you will see the output as shown below.

systemctl status getty@tty1.service

It is easy to see that the orange character in the diagram corresponds to %I in the configuration file above, and the name of the configuration file is not getty@tty1.service but getty@.service, which is called “template instance”.

To start it, just add the parameter that needs to be filled in the %I position after @, e.g. getty@tty9.service.

Target

In general, there are two common Targets: multi-user.target, which represents the multi-user command line state, and graphical.target, which represents the graphical user state (which depends on multi-user.target), much like SysVinit’s runlevel .

A very clear official Target dependency diagram is provided as follows.

Target dependency diagram

https://www.freedesktop.org/software/systemd/man/bootup.html#System Manager Bootup

Configuration file

Using the file multi-user.target as an example, let’s briefly explain the main items in Target’s configuration file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# /lib/systemd/system/multi-user.target
#
#  SPDX-License-Identifier: LGPL-2.1+
#
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes
  • Requires : Requirement to run with a Target
  • Conflicts : conflicting Targets
  • After : Which Targets to start after
  • AllowIsolate : Whether to allow switching to this Target using the systemctl isolate command