May 21, 2024 by Thibault Debatty | 527 views
Systemd is now the defacto standard init process on Linux systems. It is responsible for starting all required services… In this blog post we will present the basic concepts of systemd : basic usage, units and dependencies.
When the system boots, systemd is the first running process (pid 1).
Systemd is then responsible for starting all required services.
Unlike older init systems (System V and Upstart), Systemd provides additional features:
We will cover these features in the followup blog post.
Systemd also integrates other services that were previously separate systems:
Systemd configuration is defined in unit files. You can list systemd units with:
systemctl list-units --all
You can get more information about a single Unit with:
sudo systemctl status <unit>
For example:
sudo systemctl status cron.service
Systemd has a built-in journal (logging) system. So you can get the log messages generated by a Unit with:
journalctl --unit=<unit>
You can manually start or stop a Unit with the following command. Remember that this is a one-shot and will not restart the unit after a reboot:
systemctl start <unit>
systemctl stop <unit>
The following command allows to enable or disable a unit at boot (more about this below):
systemctl enable <unit>
systemctl disable <unit>
As you may have noticed in the output of the systemctl list-units --all
command, systemd defines diferent types of units. You can recognize them by their suffix:
Systemd configuration is defined in unit files. These files can be found in different places:
/usr/lib/systemd/system
or /lib/systemd/system
and is managed by your distribution maintainer (so you should not modify stuff here);/etc/systemd/system
and contains local configuration units;/run/systemd/system
that contains runtime unit definitions.You can check the exact location of these directories on your system with:
systemctl -p UnitPath show
Unit files are regular text files, very similar to ini
files. Here is a simplified example for a service Unit:
[Unit]
Description=Description of the Unit
Wants=otherunit.service
[Service]
Type=oneshot
ExecStart=/command/to/execute
In this simple example:
To illustrate units, create the file /etc/systemd/system/test1.target
with the following content:
[Unit]
Description=Test 1
Wants=test2.service
And the file /etc/systemd/system/test2.service
with the following content:
[Unit]
Description=Test 2
[Service]
Type=oneshot
ExecStart=echo "hi!"
Each time you create or modify unit files, don’t forget to reload unit definitions:
sudo systemctl daemon-reload
You can now activate test1.target with:
sudo systemctl start test1.target
If all went well, test1.target should be activated, and test2.service should have been executed once :
systemctl status test1.target test2.service
Also, the messages of test2.service (“hi!”) should appear in the journal:
journalctl --unit=test2.service
In the previous example, we have shown how to define dependencies between units. There are actually other configuration directives to define dependencies:
A
Requires B
:
A
is started, systemd will start B
B
is stopped, systemd will stop A
A
Wants B
:
A
is started, systemd will start B
B
is stopped, A
will keep runningA
Requisite B
:
A
is started, systemd will first start B
A
Conflicts B
:
A
is started, systemd will stop B
Next to these explicit dependencies, systemd also supports implicit dependencies, based on names. This is for example used to link a resource unit to the corresponding service (we will cover this in the followup post).
You can view the unit dependencies with
systemctl list-dependencies
Systemd uses multiple trees (a forest) to keep track of unit dependencies. This allows to easily determine which units must be started an when. The main tree, which is used for the boot process, starts with the default.target
unit.
Next to direct dependencies that we have show above, you can also ‘attach’ your unit to some other parent unit. To do so you must:
[Install]
section in your unit definition, like this one:[Install]
WantedBy=otherunit
For example, create the file /etc/systemd/system/test3.service
with the following content:
[Unit]
Description=Test3
[Service]
Type=oneshot
ExecStart=echo "hi!"
[Install]
WantedBy=test1.target
This service can be enabled, which will link the unit to its parent:
systemctl enable test3.service
When you enable test3.service
, systemd automatically adds a Wants
dependency from test1
to test3
. This ensures that test3.service
will also be activated when test1.target
is started.
Remember that only units with an Install
section can be enabled.
If you want your unit to be started at boot, you should typically add an Install section and indicate that your unit is WantedBy
another unit which you know will be activated on boot. Here is a list of some common target units, where you could “attach” your unit:
basic.target
: Basic Systemmulti-user.target
: Multi-User Systemgraphical.target
: Graphical Interfacenetwork-online.target
: Network is OnlineYou can also list all targets on your system with
systemctl list-units --all --type=target
Want to know more about systemd? Have a look at our second post in the series, where we cover systemd process tracking and resource units
This blog post is licensed under CC BY-SA 4.0