Understanding systemd

  • The widely used beast among initialization processes is systemd. The systemd will take full control of the system, right after the kernel is loaded. After that, systemd will pull the strings on entire system including services, runlevels (targets), sockets, and all other unit files.
  • Systemd runs targets unit files and each target unit file defines which service is going to start with the help of service unit files. Unit files describe how given service, or target, or socket, will behave, what it needs, does it need dependencies, does it need to be ran before certain service, or after it…
  • If your system has /usr/lib/systemd, it is powered by systemd init. Main configuration file for systemd is /etc/systemd/system.conf.

1. Introduction to Unit Files

Systemd Unit files define a service, group of services, or an action. Each unit has name, type, and configuration file. There are 12 systemd unit types and utility to manage all of them is called systemctl.

1.1 What are Unit Files?

Service unit file contains information such as which environment file to use, when a service must be started, what targets want from this service… These configuration files are placed in different directories. Location of a file is critical, because once found in two places, one gets precedence over another. The following directories contain unit files:

  1. /etc/systemd/system/ – Highest priority
  2. /run/systemd/system/ – Lower priority
  3. /usr/lib/systemd/system/ – Lowest priority

To see all unit files present, use systemctl command:

[aldin@arch systemd]$ systemctl list-unit-files
UNIT FILE                                  STATE           VENDOR PRESET
proc-sys-fs-binfmt_misc.automount          static          -            
-.mount                                    generated       -            
boot.mount                                 generated       -            
dev-hugepages.mount                        static          -            
dev-mqueue.mount                           static          -            
home.mount                                 generated       -            
proc-sys-fs-binfmt_misc.mount              disabled        disabled     
sys-fs-fuse-connections.mount              static          -            
sys-kernel-config.mount                    static          -            
sys-kernel-debug.mount                     static          -            
sys-kernel-tracing.mount                   static          -            
tmp.mount                                  static          -            
session-1.scope                            transient       -            
accounts-daemon.service                    disabled        disabled     
apparmor.service                           disabled        disabled     
auditd.service                             disabled        disabled     
autovt@.service                            alias           -            
avahi-daemon.service                       disabled        disabled     
avahi-dnsconfd.service                     disabled        disabled     
blk-availability.service                   disabled        disabled     
bluetooth-mesh.service                     disabled        disabled     
bluetooth.service                          disabled        disabled     
bolt.service                               static          -            
btrfs-scrub@.service                       static          -            
canberra-system-bootup.service             disabled        disabled     
canberra-system-shutdown-reboot.service    disabled        disabled     
canberra-system-shutdown.service           disabled        disabled     
colord.service                             static          -           

The STATE column shows state of a service. It can be enabled, disabled, static, plus nine more states which are not that common.

  • enabled: Service starts at boot time
  • disabled: Service does not start at boot time
  • static: Service starts only if another unit depends on it.

More on the unit file states later in this chapter.

1.2 Types of systemd Unit Files

All systemd unit files live inside /usr/lib/systemd/system/ directory:

  1. .service – unit files that describes how certain service will behave on the server. Includes how to start or stop the service, when it should be started, dependencies of a service…
  2. .mount – unit file that defines a mount point on the system to be managed by systemd. These are named after the mount path where slashes are changed to dashes. Entries in /etc/fstab can have unit files created automatically
  3. .timer – replacemenet for cron to start jobs
  4. .automount – unit file that automatically mounts anything on a mount points at boot time
  5. .target – collection of unit files that are started at boot time (similar to runlevels)
  6. .path – Monitoring activities in a directories
  7. .socket – unit that describes network socket. These files always have .service file associated that is started when a .socket unit file is called.
  8. .swap – unit file that describes swap space on the system.
  9. .snapshot – unit file that is created by systemctl snapshot command. Allows to reconstruct current state of the system.
  10. .slice – unit file is associated with Linux Control Group nodes.
  11. .device – unit that describes a device that needs systemd management. This decision is done by udev or sysfs filesystem.
  12. .scope – unit files created automatically by systemd from information received from its bus interfaces.

1.3 Viewing Unit Files

A unit file has parameters that systemd uses to manage and run given unit. To see the contents of each unit file, type:

[aldin@arch] $ systemctl cat haproxy.service

To see dependencies of a unit, that is, all services that will be started when a given unit is started, in a tree-like manner, type:

[aldin@arch] $ systemctl list-dependencies haproxy.service

To see dependencies of a unit, and all dependencies of those dependencies, in a tree-like manner, add –all switch:

[aldin@arch] $ systemctl list-dependencies haproxy.service --all

To see all low-level details of the unit’s settings, use ‘show’ option. This gives you key-value pairs of all parameters managed by systemd for this unit file.

[aldin@arch] $ systemctl show haproxy.service

1.4 Modifying Unit Files

Modifying unit files can be done through systemctl command. To edit a unit file snippet (not original unit file) we use edit subcommand. This will create new file that overwrites directives in original unit file

[aldin@arch] $ sudo systemctl edit haproxy.service

However, if we want to edit entire unit file, use –full switch:

[aldin@arch] $ sudo systemctl edit haproxy.service --full

After modifying unit file, reload the service unit files with daemon-reload

[aldin@arch] $ sudo systemctl daemon-reload

1.5 Service Unit File Sections

Each service unit file has three primary configuration sections:

  1. [Unit]
  2. [Service]
  3. [Install]

[Unit] Section

Basic directives withing [Unit] section are as follows:

After=The units listed here will start before the current unit starts
Before=The units listed here will not start until the current unit starts
Description=Brief description of a unit
Documentation=Set URL or man page to point to documentation source.
Conflicts=Do not start listed units when current unit is started
Requires=Current unit and listed units start in parallel. If current unit started, Requires= units must also start. Otherwise, the unit will fail.
BindsTo=Similar to Requires= directive. Listed units must start together with current unit. Otherwise, the unit will fail.
Wants=Start Wants= units with current unit. If Wants= units do not start, the current unit will start anyway.

[Service] Section

ExecReloadScript or command to be executed when unit is reloaded
ExecStartScript or command to be executed when unit is started
ExecStopScript or command to be executed when unit is stopped
EnvironmentChange environment variables with this/these
EnvironmentFileFile that contains environment variables to be replaced
RemainAfterExitIf set to ‘yes’ the service is active even when process started by ExecStart terminates.
If set to ‘no’ the service calls ExecStop when process started by ExecStart terminates.
RestartService is restarted when process started by ExecStart terminates.
TypeSet the startup type

[Install] Section

Alias=Set additional name for service to be used with systemctl command
Also=Set additional units that can be enabled or disabled together with current unit within one systemctl command.
RequiredBy=Specify units that require this service
WantedBy=Specify which target unit manages this service

1. 6 List Unit Files

To list all ‘active’ unit files we just call systemctl command

[aldin@arch ~]$ systemctl list-units --no-pager

To list all unit files, no matter their state, we use –all switch

[aldin@arch ~]$ systemctl list-units --all

The list-units pulls all files from /usr/lib/systemd/system directory and outputs on the screen. The output is organized and easy to read. Columns UNIT, LOAD, ACTIVE, SUB, and DESCRIPTION will show basic information about each unit file. They are organized in cells, so all types of unit files are grouped.

1.7 Understanding Targets

The systemd targets are nothing more than groups of Unit files. They are not runlevels. Target file runs all services that have WantedBy directive in their unit files. When systemd is starting, it loads default.target. This target is symbolic link to real target in /usr/lib/systemd/system directory.

[aldin@arch system]$ readlink /usr/lib/systemd/system/default.target 
graphical.target

[aldin@arch systemd]$ systemctl get-default 
graphical.target

There are three main .target files that start groups of services at boot.

  • graphical.target – Provides multiple users access to the system. GUI is also enabled.
  • multi-user.target – Provides multiple users access to the system via local terminals and through the network. No GUI is enabled here.
  • runlevelX.target – Provides backward compatibility with SysV init systems. X is for SysV runlevel numbers (1-5)

To see default.target unit file use cat and specify full path, or use systemctl cat default.target

[aldin@arch system]$ systemctl cat /usr/lib/systemd/system/default.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=Graphical Interface
Documentation=man:systemd.special(7)
Requires=multi-user.target
Wants=display-manager.service
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target display-manager.service
AllowIsolate=yes

2. Understanding systemctl Command

The systemctl command is used to manage systemd and system services. Let’s cover systemctl sub-commands used to manipulate services:

$ sudo systemctl [COMMAND] [SERVICE.unit] 
daemon-reloadRestart unit configuration file without stopping the service
disableDo not run service at boot time
enableRun this service at boot time
maskPrevent unit from starting. This service would not be able to started or enabled
restartStop and restart this service. If it is not running, it will start it
startStart this unit
stopStop this unit
statusShow unit’s status
reloadLoad the service configuration file and apply them, without stopping the service
unmaskUndo the mask settings
is-activeShows if service is active or not
is-enabledShows if service is enabled or not
is-failedShows if service is in failed state or not

Difference between daemon-reload and reload are as follows:

  • Use daemon-reload to load systemd unit file configuration changes for a service
  • Use reload to load service’s configuration file.

Leave a Reply