- 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:
- /etc/systemd/system/ – Highest priority
- /run/systemd/system/ – Lower priority
- /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:
- .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…
- .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
- .timer – replacemenet for cron to start jobs
- .automount – unit file that automatically mounts anything on a mount points at boot time
- .target – collection of unit files that are started at boot time (similar to runlevels)
- .path – Monitoring activities in a directories
- .socket – unit that describes network socket. These files always have .service file associated that is started when a .socket unit file is called.
- .swap – unit file that describes swap space on the system.
- .snapshot – unit file that is created by systemctl snapshot command. Allows to reconstruct current state of the system.
- .slice – unit file is associated with Linux Control Group nodes.
- .device – unit that describes a device that needs systemd management. This decision is done by udev or sysfs filesystem.
- .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:
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.|
|ExecReload||Script or command to be executed when unit is reloaded|
|ExecStart||Script or command to be executed when unit is started|
|ExecStop||Script or command to be executed when unit is stopped|
|Environment||Change environment variables with this/these|
|EnvironmentFile||File that contains environment variables to be replaced|
|RemainAfterExit||If 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.
|Restart||Service is restarted when process started by ExecStart terminates.|
|Type||Set the startup type|
|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-reload||Restart unit configuration file without stopping the service|
|disable||Do not run service at boot time|
|enable||Run this service at boot time|
|mask||Prevent unit from starting. This service would not be able to started or enabled|
|restart||Stop and restart this service. If it is not running, it will start it|
|start||Start this unit|
|stop||Stop this unit|
|status||Show unit’s status|
|reload||Load the service configuration file and apply them, without stopping the service|
|unmask||Undo the mask settings|
|is-active||Shows if service is active or not|
|is-enabled||Shows if service is enabled or not|
|is-failed||Shows 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.