systemd daemon¶Inhaltsverzeichnis
The program systemd is the process with process ID 1. It is responsible
for initializing the system in the required way. systemd is started
directly by the Kernel and resists signal 9, which normally kills
processes. All other programs are either started directly by systemd or
by one of its child processes.
![]() | Using System V init rather than systemd |
|---|---|
Being fully compatible, both | |
Starting with openSUSE 12 systemd is a replacement for the popular
SysV init daemon. systemd is fully compatible with SysV init (by
supporting init scripts). One of the main advantages of systemd is the
fact that it considerably speeds up boot time by aggressively paralleling
service starts.
Services depend on each other. The sshd daemon for example, requires the network
to be set up before it can be started. Each service provides a socket
accepting connections or a mount point in the filesystem. Starting
sshd is only successful if all
sockets it connects to, are available. Using SysV this results in
serializing the services startup - a service is not started until all other
services it depends on, have been successfully started.
systemd has a different approach. First thing it does is to provide
sockets and mount points for all services. Afterwards all services are
started at once and get „their“ socket passed on execution.
This allows to considerably speed up the boot process by starting all
services in parallel. Furthermore, systemd only starts a service when it
is really needed. Therefore the printing daemon cupsd is not started during boot time, but
rather when a user prints a document for the first time after having booted
the system. systemd also supports Kernel Control Groups (cgroups),
snapshotting and restoring of the system state and more. See http://www.freedesktop.org/wiki/Software/systemd/ for details.
The SysV init system utilized several different commands to handle
services— the init scripts, insserv,
telinit and others. systemd makes it easier to manage
services, since there is only one command to memorize for the majority of
service handling tasks: systemctl.
systemctl uses the command plus subcommand notation like git or zypper:
systemctl[general OPTIONS]subcommand[subcommand OPTIONS]
See man 1 systemctl for a complete manual.
![]() | Terminal Output |
|---|---|
| |
Subcommands for managing services are the same as for managing a service with SysV init (start, stop, ...). The general syntax for service management commands looks like the following:
systemdsystemctl reload|restart|start|status|stop|...<my_service(s)>.service
rc<my_service(s)>reload|restart|start|status|stop|...
systemd allows to manage several services in one go. So instead of
executing init scripts one after the other as with SysV init, you can
execute a command like the following:
systemctl start<my_1st_service>.service<my_2nd_service>.service
The following table shows a list of the most important service management
commands for systemd and SysV init:
Tabelle 6.1. Service Management Commands
|
Task |
|
SysV init subcommand |
|---|---|---|
|
Starting |
start |
start |
|
Stopping |
stop |
stop |
|
Restarting Shuts down services and starts them afterwards. If a service is not yet running it will be started. |
restart |
restart |
|
Restarting conditionally Restarts services if they are currently running. Does nothing for services that are not running. |
try-restart |
try-restart |
|
Reloading
Tells services to reload their configuration files without
interrupting operation. A typical usage would be to tell apache
to reload a modified |
reload |
reload |
|
Reloading or Restarting Reloads services if reloading is supported, otherwise restarts it. Services is not yet running it will be started. |
reload-or-restart |
n/a |
|
Reloading or Restarting conditionally Reloads a service if reloading is supported, otherwise restarts it if it is currently running. Does nothing for services that are not running. |
reload-or-try-restart |
n/a |
|
Getting detailed status information
Lists information about the status of a service. The
|
status |
status |
|
Getting short status information Shows whether a service is active or not. |
is-active |
status |
![]() | Verbosity |
|---|---|
| |
By default, systemd is not overly verbose. If a service was started
successfully, no output will be produced. In case of a failure, a short
error message will be displayed. However, systemctl
status provides means to debug startup as well as operation of
a service.
systemd comes with it's own logging mechanism („The
Journal“) that logs system messages. This allows to display the
service messages together with status messages. The
status command works similar to
tail and can also display the log messages in
different formats, making it a powerful debugging tool.
Whenever a service fails to start, use systemctl status
<my_service>.service to get a
detailed error message:
www.example.com: ~ # systemctl start apache2.service Job failed. See system journal and 'systemctl status' for details. www.example.com: ~ # systemctl status apache2.service Loaded: loaded (/lib/systemd/system/apache2.service; disabled) Active: failed (Result: exit-code) since Mon, 04 Jun 2012 16:52:26 +0200; 29s ago Process: 3088 ExecStart=/usr/sbin/start_apache2 -D SYSTEMD -k start (code=exited, status=1/FAILURE) CGroup: name=systemd:/system/apache2.service Jun 04 16:52:26 g144 start_apache2[3088]: httpd2-prefork: Syntax error on line 205 of /etc/apache2/httpd.conf: Syntax error on li...alHost>
n Service Messages
Displaying the last ten messages a service issued is the default
behavior of the status subcommand. Use the
--lines=
n parameter to change the
number of messages to show.
systemctl status ntp.service systemctl --lines=20 status ntp.service
To display a „live stream“ of service messages, use the
--follow option, which works just like tail
-f:
systemctl --follow status ntp.service
The --output=
parameter allows to change the output format of service messages. The
most important modes available are:
mode
shortThe default format. Shows the log messages with a human readable timestamp.
verboseFull output with all fields.
catTerse output without time stamps.
The service management commands mentioned in the previous section let you
manipulate services for the current session. systemd also lets you
permanently enable or disable services, so they always get automatically
started when requested or are always unavailable. You can either do this
by using the YaST module System Services (Runlevel) which acts as a consistent
frontend for both systemd and SysV init, or on the command line.
The following table shows a list of enabling and disabling commands for
systemd and SysV init:
![]() | Service Start |
|---|---|
When enabling a service on the command line, it is not started
automatically, but rather scheduled to be started with the next system
startup or runlevel/target change. In order to immediately start a
service after having enabled it, you need to explicitly run
systemctl start
| |
Tabelle 6.2. Commands for Enabling and Disabling Services
|
Task |
|
SysV init subcommand |
|---|---|---|
|
Enabling |
systemctl enable |
insserv |
|
Disabling |
systemctl disable |
insserv |
|
Checking Shows whether a service is enabled or not. |
systemctl is-enabled |
n/a |
|
Re-Enabling Similar to restarting a service, this commands first disables and then enables a service. Useful to re-enable a service with its defaults. |
systemctl reenable |
n/a |
|
Masking When „disabling“ a service, it can still be started manually. To completely disable a service, you need to mask it. Use with care. |
systemctl mask |
n/a |
|
Unmasking A service that has been masked can only be used again after it has been unmasked. |
systemctl unmask |
n/a |
After starting this YaST module with ++, it displays an overview listing all the available services and the current status of each service (disabled or enabled). Decide whether to use the module in or in . The default should be sufficient for most purposes. The left column shows the name of the service, the center column indicates its current status and the right column gives a short description. For the selected service, a more detailed description is provided in the lower part of the window. To enable a service, select it in the table then select . The same steps apply to disable a service.
For detailed control over the runlevels in which a service is started or stopped or to change the default runlevel, first select . The current default runlevel or „initdefault“ (the runlevel into which the system boots by default) is displayed at the top. Normally, the default runlevel of a openSUSE system is runlevel 5 (full multiuser mode with network and X). A suitable alternative might be runlevel 3 (full multiuser mode with network).
This YaST dialog allows the selection of one of the runlevels as the new default. Additionally, use the table in this window to enable or disable individual services and daemons. The table lists the services and daemons available, shows whether they are currently enabled on your system and, if so, for which runlevels. After selecting one of the rows with the mouse, click the check boxes representing the runlevels to define the runlevels in which the selected service or daemon should be running. Runlevel 4 is undefined to allow creation of a custom runlevel. A brief description of the currently selected service or daemon is provided below the table overview.
![]() | Faulty Runlevel Settings May Damage Your System |
|---|---|
Faulty runlevel settings may make your system unusable. Before applying your changes, make absolutely sure that you know their consequences. | |
With , decide whether a service should be activated. checks the current status. lets you enable or disable a service in the same manner as with the interface. Selecting saves the changed settings to disk.
The entire process of starting the system and shutting it down is
maintained by systemd. From this point of view, the Kernel can be
considered a background process to maintain all other processes and adjust
CPU time and hardware access according to requests from other programs.
With SysV init the system was booted into a so called
„Runlevel“. A runlevel defines how the system is started and
what services are available in the running system. Runlevels are numbered,
the most commonly known ones are 0 (shutting down the
system), 3 (multiuser with network) and
5 (multiuser with network and displaymanager).
systemd introduces a new concept by using so-called „target
units“. However it remains fully compatible to the runlevel
concept. Target units are named rather than numbered and serve specific
purposes. The targets local-fs.target and
swap.target, for example, mount local filesystems
and swap spaces.
Complex targets, such as graphical.target
(acts as an equivalent to runlevel 5 and provides multiuser with network
and displaymanager capabilities) act as „meta“ targets by
combining a subset of other targets. Since systemd makes it easy to
create custom targets by combining existing targets, it offers great
flexibility.
The following list shows a list of the most important systemd target
units. For a full list refer to man 7 systemd.special.
Selected systemd Target Units
default.target
The target that is booted by default. Not a „real“ target,
but rather a symlink to another target like
graphic.target. Can be permanently changed via
YaST (see Abschnitt 6.1.3.2, „Enabling/Disabling Services with YaST“). To change it for
a session, use the kernel command line option
systemd.unit=
at the boot screen.
<my_target>.target
emergency.target
Starts an emergency shell on the console. Only use it at the boot
prompt as systemd.unit=emergency.target.
graphical.targetStarts a system with network, multi-user support and a displaymanager.
halt.targetShuts down the system.
mail-transfer-agent.targetStarts all services necessary for sending and receiving mails.
multi-user.targetStarts a multi-user system with network.
reboot.targetReboots the system.
rescue.targetStarts a single user system without network.
In order to remain compatible to the SysV init runlevel system,
systemd provides special targets named
runlevel mapping the
corresponding runlevels numbered X.targetX.
Tabelle 6.3. SysV runlevels and systemd Target Units
|
SysV runlevel |
|
Purpose |
|---|---|---|
|
0 |
|
System shutdown |
|
1, S |
|
Single user mode |
|
2 |
|
Local multiuser without remote network |
|
3 |
|
Full multiuser with network |
|
4 |
|
Unused/User Defined |
|
5 |
|
Full multiuser with network and displaymanager |
|
6 |
|
System reboot |
Use the following commands to operate with target units:
|
Task |
|
SysV init command |
|---|---|---|
|
Change the current target/runlevel |
systemctl isolate |
telinit |
|
Change to the default target/runlevel |
systemctl default |
n/a |
|
Get the current target/runlevel |
systemctl list-units --type=target
With |
who -r or runlevel |
|
Change the default runlevel persistently |
Use the YaST runlevel editor or run the following command: ln -sf /lib/systemd/system/ |
Use the YaST runlevel editor or change the line id:
in |
|
Change the default runlevel for the current boot process |
Enter the following option at the boot prompt systemd.unit= |
Enter the desired runlevel number at the boot prompt. |
|
Show a target's/runlevel's dependencies |
systemctl show -p "Requires" systemctl show -p "Wants" „Requires“ lists the hard dependencies (the ones that must be resolved), whereas „Wants“ lists the soft dependencies (the ones that get resolved if possible). |
n/a |
On SysV init SUSE systems, runlevel 4 is unused to allow
administrators to create their own runlevel configuration. systemd
allows ro create any number of custom targets. It's suggested to start by
adapting an existing target such as
graphical.target:
Copy the configuration file
/lib/systemd/system/graphical.target to
/etc/systemd/system/
and adjust it according to your needs.
<my_target>.target
The configuration file copied in the previous step already covers the
required („hard“) dependencies for the target. To also
cover the wanted („soft“) dependencies, create a directory
/etc/systemd/system/. Create
a symbolic link from <my_target>.target.wants/lib/systemd/system for each
wanted service into this directory.
Once you have finished setting up the target, reload the systemd
configuration to make the new target available:
systemctl daemon-reload
![]() | Customization |
|---|---|
Always do | |
systemd offers means to analyze the system startup process. You can
conveniently review the list of all services and their status (rather than
having to parse /varlog/). systemd also allows to
scan the startup procedure to find out how much time each service startup
consumes.
To review the complete list of services that have been started since
booting the system, just enter the command
systemctl. It lists all active services like shown in
the following shortened example. To get more information on a specific
service, use systemctl status
<my_service>.service.
jupiter.example.com: ~ # systemctl UNIT LOAD ACTIVE SUB JOB DESCRIPTION [...] systemd-random-seed-load.path loaded active waiting Random Seed acpid.service loaded active running ACPI Event Daemon apache2.service loaded failed failed apache avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack bluez-coldplug.service loaded active exited LSB: handles udev coldplug of bluetooth dongles console-kit...-system-start.service loaded active exited Console System Startup Logging cron.service loaded active running Command Scheduler cups.service loaded active running CUPS Printing Service [...] LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type. JOB = Pending job for the unit. 107 units listed. Pass --all to see inactive units, too.
To restrict the output to services that failed to start, use the
--failed option:
jupiter.example.com: ~ # systemctl --failed UNIT LOAD ACTIVE SUB JOB DESCRIPTION apache2.service loaded failed failed apache NetworkManager.service loaded failed failed Network Manager plymouth-start.service loaded failed failed Show Plymouth Boot Screen [...]
To debug system startup time, systemd offers the
systemd-analyze command. It shows the total startup
time, a list of services ordered by startup time and can also generate an
SVG graphic showing the time services took to start in relation to the
other services.
jupiter.example.com: ~ # systemd-analyze Startup finished in 2666ms (kernel) + 21961ms (userspace) = 24628ms
jupiter.example.com: ~ # systemd-analyze blame
6472ms systemd-modules-load.service
5833ms remount-rootfs.service
4597ms network.service
4254ms systemd-vconsole-setup.service
4096ms postfix.service
2998ms xdm.service
2483ms localnet.service
2470ms SuSEfirewall2_init.service
2189ms avahi-daemon.service
2120ms systemd-logind.service
1210ms xinetd.service
1080ms ntp.service
[...]
75ms fbset.service
72ms purge-kernels.service
47ms dev-vda1.swap
38ms bluez-coldplug.service
35ms splash_early.servicejupiter.example.com: ~ # systemd-analyze plot > jupiter.example.com-startup.svg
The following sections cover advanced topics for system administrators. For
even more advanced systemd documentation, please refer Lennart Pöttering's
series about systemd for administrators at http://0pointer.de/blog/projects.
In Abschnitt 6.1.2, „Debugging Services“ we have
explained how to view log messages for given service. However, displaying
log messages is not restricted to service logs. You can also access and
query the complete log written by systemd—the so-called
„Journal“. Use the command
systemd-journalctl to display the complete log starting
with the oldest entries. Refer to man 1
systemd-journalctl for options such as applying filters or
changing the output format.
You can save the current state of the systemd System Manager to a named
snapshot and later return to it with the isolate subcommand. This is useful
when testing services or custom targets, because it allows you to return to
a defined state at any time. A snapshot is only available in the current
session and will automatically be deleted on reboot. A snapshot name must
end in .snapshot.
systemctl snapshot <my_snapshot>.snapshotsystemctl delete <my_snapshot>.snapshotsystemctl isolate <my_snapshot>.snapshotOn a traditional SysV init system it is not always possible to clearly assign a process to the service that spawned it. Some services such as Apache, spawn a lot of 3rd party processes (e.g. CGI or Java processes), which themselves spawn more processes and make a clear assignment difficult or even impossible. Whats more, a service may not terminate correctly, leaving some of its children alive.
systemd solves this problem by placing each service into it's own
cgroup. cgroups are a kernel feature that allows aggregating processes
and all their children into hierarchical organized groups. systemd names
each cgroup after its service. Since a
non-privileged process it not allowed to „leave“ its cgroup,
this provides an effective way to label all processes spawned by a service
with the name of the service.
To list all processes belonging to a service, use the command systemd-cgls. The result will look like the following (shortened) example:
~ # systemd-cgls --no-pager ├ user │ └ root │ └ 1 │ ├ 2279 sshd: root@pts/0 │ ├ 2282 -bash │ └ 2541 systemd-cgls --no-pager └ system ├ 1 /sbin/init splash showopts ├ apache2.service │ ├ 2535 /usr/sbin/httpd2-prefork -f /etc/apache2/httpd.conf -D SYSTEMD -k start │ ├ 2536 /usr/sbin/httpd2-prefork -f /etc/apache2/httpd.conf -D SYSTEMD -k start │ ├ 2537 /usr/sbin/httpd2-prefork -f /etc/apache2/httpd.conf -D SYSTEMD -k start │ ├ 2538 /usr/sbin/httpd2-prefork -f /etc/apache2/httpd.conf -D SYSTEMD -k start │ ├ 2539 /usr/sbin/httpd2-prefork -f /etc/apache2/httpd.conf -D SYSTEMD -k start │ └ 2540 /usr/sbin/httpd2-prefork -f /etc/apache2/httpd.conf -D SYSTEMD -k start ├ xdm.service │ ├ 2250 /usr/bin/xdm │ ├ 2253 /usr/bin/X -nolisten tcp -br vt7 -auth /var/lib/xdm/authdir/authfiles/A:0-ii8Goo │ ├ 2263 -:0 │ └ 2276 /usr/bin/xconsole -notify -nostdin -verbose -exitOnFail ├ ntp.service │ └ 2202 /usr/sbin/ntpd -p /var/run/ntp/ntpd.pid -g -u ntp:ntp -c /etc/ntp.conf ├ sshd.service │ └ 1743 /usr/sbin/sshd -D
See Chapter 10, Kernel Control Groups (↑System Analysis and Tuning Guide) for more information about cgroups.
As explained in Abschnitt 6.3.4, „Killing Services (Sending Signals)“, it is not always possible to assign a process to its parent service process in a SysV init system. This makes it difficult to, for example, terminate a service and all of its children. Child processes that have not been killed will remain as zombie processes.
systemd's concept of to confine each service into a cgroup makes it
possible to clearly identify all child processes of a service and therefore
allows to send a signal to each of these processes. Use systemctl
kill to send signals to services.
SIGTERM to a Service
SIGTERM is the default signal that is sent.
systemctl kill <my_service.serviceSIGNAL to a Service
Use the -s option to specify the signal that should be
sent. For a list of available signals refer to man 7
signals.
systemctl kill -sSIGNAL<my_service.service
By default the kill command send the signal
to all processes of the specified cgroup. You can
restrict it to the control or the main
process. The latter is for example useful to force a service to reload
its configuration by sending SIGHUP:
systemctl kill -s SIGHUP --kill-who=main <my_service.service
For more information on systemd refer to the following online resources:
systemd for Administrators
A series of blog entries (13 at the time of writing this chapter) from
Lennart Pöttering, one of the systemd authors, that can be found at http://0pointer.de/blog/projects.
systemd Linux init systemhttp://www.h-online.com/open/features/Control-Centre-The-systemd-Linux-init-system-1565543.html
systemd, a Linux init toolhttp://www.h-online.com/open/features/Booting-up-Tools-and-tips-for-systemd-1570630.html