Systemd is a software suite and init systems that provides system components to Linux operating systems. Its main component is the system and service manager.
Photo by Luca Bravo Unsplash
The Init program is the parent of all Linux processes. It is the first process (especially it is a daemon process) The init program is the last process that closes. If the process lost its parent init becomes the new parent of the zombie child process
It has a PID of 1 like other init systems. (System V, Upstart)
If systemd is used for init, /sbin/init
file links to /lib/systemd/systemd
SystemV Init
It is a traditional init system. It runs specific services at specific runlevels. Linux machine works at a specific runlevel at any time. Runlevel goes from 0 to 6(single-user mode, multi-user, shutdown, … )
Upstart
Its Canonical’s implementation of SystemV.
Systemd uses targets rather than runlevels.
Systemd runs services as parallel contrary to SystemV. For this reason, init time decreased.
Systemd uses cgroup for simplifying daemon or service management. Spawned processes belong to their parent cgroup. These processes do not leave from cgroup unless their parent terminates themselves. (For brief overview to cgroups)
Related processes are grouped under cgroup. cgroups are managed with systemd slices.
We can list all slices by systemctl -t slice --all
For listing systemd control groups we can type
systemd-cgls
Resource constraints in the SystemV environment are managed at the /etc/security/limits.conf
file and /etc/security/limits.d
directory.
Systemd configuration files are written in a declarative format so writing configuration for Systemd is easy. Systemd uses shell scripts to manage the system.
Systemd does not only manage processes. It manages also
- Network connections (
networkd
) - Kernel messages (
journald
) - Logins (
logind
)
Default unit files of systemd are managed under the directory /lib/systemd/system
.
User-specific configurations are often managed under /etc/systemd/system
.
The vendor of the unit file tenders the unit file in the /lib/systemd/system
directory and if the user wants to override the default configuration,
he/she puts the changed unit file with the same name in the /etc/systemd/system
. The unit file under /etc
directory has more precedence than
the unit file under /lib
directory.
Unit Types in Systemd
Service
Describes expressions for managing services that are controlled by systemd. Ends with the suffix .service
Socket
Holds information about IPC and network sockets in Linux system. Ends with the suffix .socket
Target
Synchronizes services in the boot time. For example, if the service requires a service to start, or target (like network.target). Ends with the suffix .target
Device
Devices, which are exposed with udev and sysfs. Ends with the suffix .device
.
Mount
Mount point of file systems that are managed by systemd. Ends with the suffix .mount
Automount
The automount capabilities.
Timer
Synonym of cron. Schedules activation of other units. Ends with .timer
suffix.
Swap
Specifies the memory swap partition.
Path
If any files are changed in a specified path, unit files may be activated and started. Ends with the suffix .path
Slice
It is a custom unit. It is used together with services, daemons, and cgroups for resource management in a hierarchical tree form. Ends with the suffix .slice
Scope
It manages processes that are created externally from systemd. It ends with the suffix .scope
but it is not configured with files. Instead, it
is configured programmatically by using systemd’s dbus interfaces.
The Scope units do not fork the process that they own.
A new scope can be started with systemd-run --scope
. This process is started by systemd-run
and not by systemd
which has a PID of 1. For example:
systemd-run --scope /bin/bash
- With memory limit:
systemd-run --scope -p MemoryLimit=1G firefox
The services’ lifetime is equal to the lifetime of the main process of service. Scope lifetime continues until no process exists in scope.
Scopes manage the process and slices manage unit files (services, scopes, other slices, etc. )
Scopes are generally used for processes that are started by systemd. If a service unit file (.service) is used for starting a process, using scopes may be redundant.
The systemd process itself is under root.slice
. It can’t be a service. System services are grouped under system.slice
and user services are
grouped under user.slice
.
After the target is activated, targets that depend on that target are activated. Vary dependency types exist for dependency management:
- Requires: The service is not started until the dependent service is started. (strict form)
- Wants: The service is started after the dependent service is started. It is started regardless of whether the dependent service can be successfully started or not.
- Conflicts: If the service that is written to this section is started, the configured service is terminated immediately.
- Requisite: The dependents that are written here should be active before the configured unit is activated. It is similar to the Require but if the dependent unit is not active, the dependent unit is not started automatically and the configured unit fails.
- Before: The unit is started before a unit. It only determines the order.
- After: The unit is started after a unit. It only determines the order.
- Conditional Dependencies: The unit is not started if the specified condition evaluates to false.
For listing units: systemctl list-units
Example unit file (docker.service
):
Drop-Ins
It is possible to change configurations of the unit files by not changing files under /etc/systemd/system
using Drop-Ins. The systemd-delta
command can be used
for listing changes.
Example with a service named foo.service
For the drop-in configuration create /etc/systemd/foo.service.d/00-foo.conf
file. The filename is not important but for ordering configurations number prefixes
can be added to the filename.
[Service]
ExecStart=
ExecStart=/usr/bin/stress - cpu 1 - vm 1 - io 1 - vm-bytes 128M
The first ExecStart
with an empty value is required.
Systemd daemon should be reloaded after the file is created: systemctl daemon-reload
After the service is restarted the new configuration will override the configuration of /etc/systemd/foo.service
Also, we can use systemctl edit <unit>
for creating drop-ins.
We can revert back to the vendor-specific version with: systemctl revert <unit>