
5 reasons to love systemd
There’s a lot happening on modern computers. Applications run in the background, automated events wait to be triggered, log files get written, and status reports are delivered. These disparate processes have traditionally been managed and monitored with a collection of UNIX tools, to great effect and with great efficiency. However, modern computers are diverse, with local services running alongside containerized applications, easy access to clouds and the clusters they run on, realtime processes, and more data to process than ever. A unified method of managing them is an expectation for users, and a useful luxury for the busy systems adminstrator. For this nontrivial task, the System Daemon, or systemd, was developed and quickly adopted by all of the major Linux distributions.
Of course, systemd isn’t the only way to manage a Linux system. There are many alternative init systems, including sysvinit, OpenRC, runit and s6, and even BusyBox, but systemd treats Linux as a unified data set, meant to be manipulated and queried in a consistent manner with robust tools. For a busy systems administrator, and for many users, the speed and ease of systemd is an important feature.
1. Boot management
Booting a Linux computer can be a surprisingly rare event, if you want it to be. Certainly in the server world, uptimes are often counted in years rather than months or weeks. Laptops and desktops tend to be shutdown and booted pretty frequently, although even these are as likely to be suspended or hibernated as they are to be shutdown. Either way, the time since the most recent boot event can serve as a sort of session manager for a computer health check. It’s a useful way to limit what data you look at when monitoring your system or diagnosing problems.
In the likely event that you can’t remember the last time you booted your computer, you can list boot sessions with systemd’s logging tool, journalctl.
$ journalctl --list-boots
-42 7fe7c3... Fri 2020-12-04 05:13:59 - Wed 2020-12-16 16:01:23
-41 332e99... Wed 2020-12-16 20:07:39 - Fri 2020-12-18 22:08:13
[...]
-1 e0fe5f... Mon 2021-03-29 20:47:46 - Mon 2021-03-29 21:59:29
0 37fbe4... Tue 2021-03-30 04:46:13 - Tue 2021-03-30 10:42:08
The latest boot sessions appear at the bottom of the list, so you can pipe the output to tail
for just the latest boots.
2. Logs and queries
Looking at logs is an important method of extrapolating information about your system. Logs provide a history of much of the activity your computer engages in without your direct supervision. You can see when services were launched, when timed jobs were run, what services are running in the background, which activities failed, and more. One of the most common initial troubleshooting steps is to review logs, which is easy to do with journalctl
:
$ journalctl --pager-end
The --pager-end
(or -e
for short) option starts your view of your logs at the end of the journalctl
output, such that you must scroll up to see events happening earlier in history.
A “catalog” of errors and messages is maintained by systemd, and this is filled with records of errors, possible solutions, pointers to support forums, and developer documentation. This can provide important context to a log event, which can otherwise be a confusing blip in a sea of messages, or worse could go entirely unnoticed. To integrate error messages with explanatory text, you can use the --catalog
(or -x
for short) option.
$ journalctl --pager-end --catalog
To further limit the log output you must wade through, you can specify which boot session you want to see logs for. Each boot session is numbered, so you can provide specific sessions with the --boot
option, and view only logs that apply to it:
$ journalctl --pager-end --catalog --boot 13
You can also see logs just for a specific systemd unit. For instance, were you to troubleshoot an issue with your SSH service, you can specify --unit sshd
to see only logs applying to the sshd
daemon.
$ journalctl --pager-end \
--catalog --boot 13 \
--unit sshd
3. Service management
The first job systemd is tasked with is booting your computer, and it generally does that promptly, efficiently, and effectively. But the task that’s never done is service management. By design, systemd ensures that services you want running are started, and that they continue to run during your session. Your interface to help systemd manage services is the systemctl
command. With it, you can view the unit files defining a service:
$ systemctl cat sshd
# /usr/lib/systemd/system/sshd.service
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.target
Wants=sshd-keygen.target
[Service]
Type=notify
EnvironmentFile=-/etc/crypto-policies/back-ends/opensshserver.config
EnvironmentFile=-/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS $CRYPTO_POLICY
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
Most unit files exist in /usr/lib/systemd/system/
, but as with many important configurations, you’re encouraged to modify them with local changes.
There’s an interface for that, too:
$ systemctl edit sshd
You can see whether a service is currently active:
$ systemctl is-active sshd
active
$ systemctl is-active foo
inactive
Similarly, you can see whether a service has failed with is-failed
.
Starting and stopping services is nicely intuitive:
$ systemctl stop sshd
$ systemctl start sshd
And enabling a service to be started at boot time is simple:
$ systemctl enable sshd
Add the --now
option to enable a service to be started at boot time, and to also start it for your current session.
4. Timers
Long ago, when you wanted to automate a task on Linux, the canonical tool for the job would have been cron
. There’s still a place for the cron command, but there are also alternatives. Scheduled events are little more than services activated at a specific time, so systemd manages a cron-like function called timers. You can list active timers:
$ systemctl list-timers
NEXT LEFT
Tue 2021-03-30 12:37:54 NZDT 16min left [...]
Wed 2021-03-31 00:00:00 NZDT 11h left [...]
Wed 2021-03-31 06:42:02 NZDT 18h left [...]
3 timers listed.
Pass --all to see loaded but inactive timers, too.
You can enable a timer the same way you enable a service:
$ systemctl enable myMonitor.timer
5. Targets
The final major component of the systemd matrix are targets. A target is defined by a unit file, the same as services and timers. They can be started and enabled in the same way, too. What makes targets unique is that they group other unit files together in an arbitrarily significant way. For instance, sometimes you might want to boot to a text console instead of a graphical desktop, so the multi-user
target exists. However, the multi-user
target is only the graphical
target without the desktop unit files as dependencies.
Targets are, in short, easy ways for you to collect services and timers and even other targets together to represent an intended state for your machine.
In fact within systemd, a reboot or a poweroff or a shutdown action is just another target.
You can list all available targets using the list-unit-files
option, constraining it with the --type
option set to target
:
$ systemctl list-unit-files --type target
Take control with systemd
Modern Linux uses systemd for service management and log introspection. It has provided personal Linux systems as well as servers with a modern mechanism for monitoring and easy maintenance. The more you use it, the more systemd becomes comfortably predictable and intuitive, and the more disparate parts of your system are revealed to be interconnected. To get better acquainted with systemd, you must use it.