quick-docs/modules/ROOT/pages/systemd-understanding-and-administering.adoc
2023-08-28 22:44:35 +02:00

607 lines
22 KiB
Text

= Understanding and administering systemd
Christopher Engelhard; Kamil Páral; Caleb McKee
:revnumber: unknown
:revdate: 2020-08-05
:category: Administration
:tags: How-to, Upgrade
:source-highlighter: prettify
:page-aliases: understanding-and-administering-systemd.adoc
[abstract]
Learn the basic principles of the _systemd_ init system: how to configure it and use it to administer the system.
== Understanding systemd
_Systemd_ is a system and service manager for Linux, compatible with SysV and LSB init scripts. _Systemd_ provides:
* Aggressive parallelization capabilities
* Uses socket and D-Bus activation for starting services
* Offers on-demand starting of daemons, keeps track of processes using Linux cgroups
* Supports snapshotting and restoring of the system state
* Maintains mount and automount points
* Implements an elaborate transactional dependency-based service control logic.
The `systemctl` command is the primary tool to manage _systemd_. It combines the functionality of SysVinit's `service` and `chkconfig` commands into a single tool you can use to enable and disable services permanently or only for the current session.
_Systemd_ manages so-called *_units_*, which are representations of system resources and services. This following list shows the unit types that _systemd_ can manage:
service::
A service on the system, including instructions for starting, restarting, and stopping the service.
socket::
A network socket associated with a service.
device::
A device specifically managed with _systemd_.
mount::
A mountpoint managed with _systemd_.
automount::
A mountpoint automatically mounted on boot.
swap::
Swap space on the system.
target::
A synchronization point for other units. Usually used to start enabled services on boot.
path::
A path for path-based activation. For example, you can start services based on the state of a certain path, such as whether it exists or not.
timer::
A timer to schedule activation of another unit.
snapshot::
A snapshot of the current _systemd_ state. Usually used to rollback after making temporary changes to _systemd_.
slice::
Restriction of resources through Linux Control Group nodes (cgroups).
scope::
Information from _systemd_ bus interfaces. Usually used to manage external system processes.
== Starting, stopping, and querying systemd services
You can perform various management tasks to control _systemd_ services using the `systemctl` command. The following is a set of example commands to demonstrate how to use `systemctl` to manage _systemd_ services.
[discrete]
== Prerequisites
You are logged in as a user with administrator-level permissions.
[discrete]
== Procedure
The following commands control the `foo` service:
* Activate a service immediately:
+
----
# systemctl start foo
----
* Deactivate a service immediately:
+
----
# systemctl stop foo
----
* Restart a service:
+
----
# systemctl restart foo
----
* Show the status of a service including, whether it is running or not:
+
----
# systemctl status foo
----
* Enable a service to be started on boot:
+
----
# systemctl enable foo
----
* Disable a service to not start during boot:
+
----
# systemctl disable foo
----
* Prevent a service from starting dynamically or even manually unless unmasked:
+
----
# systemctl mask foo
----
* Check if a service is enabled or not:
+
----
# systemctl is-enabled foo
----
[discrete]
=== Related Information
* Run `man systemctl` for more details.
== Modifying existing systemd services
This example shows how to modify an existing service. Service modification are stored within `/etc/systemd/system`, in a single file or in a subdirectory named after the service. For example, this procedure modifies the `httpd` service.
[discrete]
=== Prerequisites
* You are logged in as a user with administrator-level permissions.
* You have a configured `httpd` server running through _systemd_.
[discrete]
=== Procedure
. _Systemd_ services can be modified using the `systemctl edit` command.
+
----
# systemctl edit httpd.service
----
+
This creates an override file `/etc/systemd/system/httpd.service.d/override.conf` and opens it in your text editor. Anything you put into this file will be *added* to the existing service file.
. Add your custom configuration. For example:
+
----
[Service]
Restart=always
RestartSec=30
----
+
To replace an option that can be set multiple times, it must cleared first, otherwise the override file will add the option a second time.
+
----
[Service]
ExecStart=
ExecStart=<new command>
----
. Save the file. _Systemd_ automatically loads the new service configuration.
. Restart the `httpd` service:
+
----
# systemctl restart httpd
----
To completely replace (instead of just add to/modify) an existing service file, use `systemctl edit --full`, e.g. `systemctl edit --full httpd.service`. This will create `/etc/systemctl/system/httpd.service`, which will be used instead of the existing service file.
[discrete]
=== Related Information
* See link:#common-service-parameters[Common service parameters] for more information about the parameters used in this procedure.
== Creating new systemd services
This example shows how to create a unit file for a custom service. Custom unit files are located in `/etc/systemd/system/` and have a `.service` extension. For example, a custom `foo` service uses `/etc/systemd/system/foo.service` unit file.
[discrete]
=== Prerequisites
* You are logged in as a user with administrator-level permissions.
[discrete]
=== Procedure
This procedure creates a basic configuration file to control the `foo` service.
. Create and edit the new configuration file:
+
----
# nano /etc/systemd/system/foo.service
----
. The next few steps describe each section its parameters to add to the file:
.. The `[Unit]` section provides basic information about the service. The `foo` service uses the following parameters:
+
`Description`::
A string describing the unit. _Systemd_ displays this description next to the unit name in the user interface.
`After`::
Defines a relationship with a second unit. If you activate the unit, _systemd_ activates it only after the second one. For example, the `foo` service might require network connectivity, which means the `foo` services specifies `network.target` as an `After=` condition.
+
The resulting `[Unit]` section looks like this:
+
----
[Unit]
Description=My custom service
After=network.target
----
.. The `[Service]` section provides instructions on how to control the service. The `foo` service uses the following parameters:
+
`Type`::
Defines the type of _systemd_ service. In this example, the `foo` service is a `simple` service, which starts the service without any special consideration.
`ExecStart`::
The command to run to start the service. This includes the full path to the command and arguments to modify the service.
+
The resulting `[Service]` section looks like this:
+
----
[Service]
Type=simple
ExecStart=/usr/bin/sleep infinity
----
.. The `[Install]` section provides instructions on how _systemd_ installs the service. The `foo` service uses the following parameters:
+
`WantedBy`::
Defines which service triggers the custom service if enabled with `systemctl enable`. This is mostly used for starting the custom service on boot. In this example, `foo.service` uses `multi-user.target`, which starts `foo.service` when _systemd_ loads `multi-user.target` on boot.
. The full `foo.service` file contains the following contents:
+
----
[Unit]
Description=My custom service
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/sleep infinity
[Install]
WantedBy=multi-user.target
----
+
Save the file.
. To make _systemd_ aware of the new service, reload its service files
+
----
# systemctl daemon-reload
----
. Start the custom `foo` service:
+
----
# systemctl start foo
----
. Check the status of the service to ensure the service is running:
+
----
$ systemctl status foo
● foo.service - My custom service
Loaded: loaded (/etc/systemd/system/foo.service; static; vendor preset: disabled)
Active: active (running) since Thu 2017-12-14 14:09:12 AEST; 6s ago
Main PID: 31837 (sleep)
Tasks: 1 (limit: 4915)
CGroup: /system.slice/foo.service
└─31837 /usr/bin/sleep infinity
Dec 14 14:09:12 dansmachine systemd[1]: Started My custom service.
----
[discrete]
=== Related Information
* See link:#common-service-parameters[Common service parameters] for more information about the parameters used in this procedure.
== Converting SysVinit services to systemd
Older versions of Fedora use SysVinit scripts to manage services. This section provides some guidelines on how to convert a SysVinit script to a _systemd_ equivalent.
[discrete]
=== Prerequisites
* You are logged in as a user with administrator-level permissions.
* You have a custom SysVinit script to convert to a _systemd_ configuration.
[discrete]
=== Procedure
. Identify the runlevels in your SysVinit script. This is usually defined with `chkconfig` directive in the commented section at the beginning of the script. For example, the following indicates the service is using runlevels 3, 4, and 5:
+
----
# chkconfig: 235 20 80
----
+
systemd uses targets instead of runlevels. Use the table in <<#converting-sysvinit-services>> to map the runlevels to targets. In this example, runlevels 2, 3, and 5 are all multi-user runlevels, so the _systemd_ service can use the following:
+
----
[Install]
WantedBy=multi-user.target
----
+
If you enable the custom _systemd_ service to start at boot (`systemctl enable foo.service`), _systemd_ loads the service when loading the `multi-user.target` at boot time.
. Identify the dependent services and targets. For example, if the custom service requires network connectivity, specify the `network.target` as a dependency:
+
----
[Unit]
Description=My custom service
After=network.target
----
. Identify the command used to start the service in the SysVinit script and convert this to the _systemd_ equivalent. For example, the script might contain a `start` function in the following format:
+
[source,bash]
----
start() {
echo "Starting My Custom Service..."
/usr/bin/myservice -D
}
----
+
In this example, the `/usr/bin/myservice` command is the custom service command set to daemonize with the `-D` option. Set the `ExecStart` parameter to use this command:
+
----
[Service]
ExecStart=/usr/bin/myservice -D
----
. Check the SysVinit script to see if the service uses a special command to restart the service. For example, the script might contain a `reboot` function that reloads the service:
+
[source,bash]
----
reboot() {
echo "Reloading My Custom Service..."
/usr/bin/myservice reload
}
----
+
In this example, the `/usr/bin/myservice` command is the custom service command and reloads the service using the `reload` subcommand. Set the `ExecReload` parameter to use this command:
+
----
[Service]
ExecReload=/usr/bin/myservice reload
----
+
Alternatively, you can omit `ExecReload` and use the default behavior, which kills the service and starts it again.
. Check the SysVinit script to see if the service uses a special command to stop the service. For example, the script might contain a `stop` function that reloads the service:
+
[source,bash]
----
reboot() {
echo "Stopping My Custom Service..."
/usr/bin/myservice shutdown
}
----
+
In this example, the `/usr/bin/myservice` command is the custom service command and stop the service gracefully using the `shutdown` subcommand. Set the `ExecStop` parameter to use this command:
+
----
[Service]
ExecStop=/usr/bin/myservice shutdown
----
+
Alternatively, you can omit `ExecStop` and use the default behavior, which kills the service.
. Review the SysVinit script and identify any additional parameters or functions. Use _systemd_ parameters to replicate any identified SysVinit functions that might be relevant to your service.
[discrete]
=== Related Information
* See link:#common-service-parameters[Common service parameters] for more information about the parameters used in this procedure.
== Common service parameters
=== Unit Parameters
This section contains parameters you can use in the `[Unit]` section of a service. These parameters are common to other _systemd_ units.
This list is a summarized version. For a full list of these parameters and their descriptions, run `man systemd.unit`.
Description::
A free-form string describing the service.
Documentation::
A space-separated list of URIs referencing documentation for this service or its configuration. Accepted are only URIs of the following types: `http://`, `https://`, `file:`, `info:`, `man:`.
Requires::
Configures requirement dependencies on other services. If this service gets activated, the units listed here are activated too. If one of the dependent services fails to activate, _systemd_ does not start this service. This option may be specified more than once or you can specify multiple space-separated units.
Wants::
Similar to `Requires`, except failed units do not have any effect on the service.
BindsTo::
Similar to `Requires`, except stopping the dependent units also stops the service.
PartOf::
Similar to `Requires`, except the stopping and restarting dependent units also stop and restart the service.
Conflicts::
A space-separated list of unit names that, if running, cause the service not to run.
Before, After::
A space-separated list of unit names that configures the ordering of dependencies between services.
OnFailure::
A space-separated list of unit names that are activated when this service enters a failed state.
=== Install Parameters
This section contains parameters you can use in the `[Install]` section of a service. These parameters are common to other _systemd_ units.
This list is a summarized version. For a full list of these parameters and their descriptions, run `man systemd.unit`.
Alias::
A space-separated list of additional names this service shall be installed under. The names listed here must have the same suffix (i.e. type) as the service filename.
RequiredBy, WantedBy::
Defines the service as dependent of another service. This usually define the target to trigger an enabled service to run. These options are analogous to the `Requires` and `Wants` in the `[Units]` section.
Also::
Additional units to install or uninstall when this service is installed or uninstalled.
=== Service Parameters
This section contains parameters you can use in the `[Service]` section of a service unit. These parameters are specific only to _systemd_ service units.
This list is a summarized version. For a full list of these parameters and their descriptions, run `man systemd.unit`.
Type::
Configures the process start-up type for this service service:
+
* `simple` - The service starts as the main process. This is the default.
* `forking` - The service calls forked processes and run as part of the main daemon.
* `oneshot` - Similar to `simple`, except the process must exit before _systemd_ starts follow-up services.
* `dbus` - Similar to `simple`, except the daemon acquires a name of the D-Bus bus.
* `notify` - Similar to `simple`, except the daemon sends a notification message using `sd_notify` or an equivalent call after starting up.
* `idle` - Similar to `simple`, except the execution of the service is delayed until all active jobs are dispatched.
RemainAfterExit::
A boolean value that specifies whether the service shall be considered active even if all its processes exited. Defaults to no.
GuessMainPID::
A boolean value that specifies whether _systemd_ should guess the main PID of a service if it cannot be determined reliably. This option is ignored unless `Type=forking` is set and `PIDFile` is not set. Defaults to yes.
PIDFile::
An absolute filename pointing to the PID file of this daemon. Use of this option is recommended for services where `Type=forking`. _Systemd_ reads the PID of the main process of the daemon after start-up of the service. _Systemd_ does not write to the file configured here, although it removes the file after the service has shut down.
BusName::
A D-Bus bus name to reach this service. This option is mandatory for services where `Type=dbus`.
ExecStart::
The commands and arguments executed when the service starts.
ExecStartPre, ExecStartPost::
Additional commands that are executed before or after the command in `ExecStart`.
ExecReload::
The commands and arguments to execute when the service reloads.
ExecStop::
The commands and arguments to execute when the service stops.
ExecStopPost::
Additional commands to execute after the service stops.
RestartSec::
The time in seconds to sleep before restarting a service.
TimeoutStartSec::
The time in seconds to wait for the service to start.
TimeoutStopSec::
The time in seconds to wait for the service to stop.
TimeoutSec::
A shorthand for configuring both `TimeoutStartSec` and `TimeoutStopSec` simultaneously.
RuntimeMaxSec::
A maximum time in seconds for the service to run. Pass `infinity` (the default) to configure no runtime limit.
Restart::
Configures whether to restart the service when the service's process exits, is killed, or reaches a timeout:
+
* `no` - The service will not be restarted. This is the default.
* `on-success` - Restart only when the service process exits cleanly (exit code 0).
* `on-failure` - Restart only when the service process does not exit cleanly (node-zero exit code).
* `on-abnormal` - Restart if the process terminates with a signal or when a timeout occurs.
* `on-abort` - Restart if the process exits due to an uncaught signal not specified as a clean exit status.
* `always` - Always restart.
== Mapping runlevels to targets
_Systemd_ targets serve a similar purpose to SysVinit runlevels but act a little differently. Each target has a name instead of a number and each serves a specific purpose. _Systemd_ implements some targets by inheriting all of the services of another target and adding additional services to it. Some _systemd_ targets mimic the common sysvinit runlevels, which means you can switch targets with the familiar `telinit RUNLEVEL` command. The runlevels assigned a specific purpose on vanilla Fedora installs (0, 1, 3, 5, and 6) have a 1:1 mapping with a specific _systemd_ target.
However, this is not the case for user-defined runlevels 2 and 4. To make use of those runlevels, create a new named _systemd_ target such as `/etc/systemd/system/$YOURTARGET` that takes one of the existing runlevels as a base, make a directory `/etc/systemd/system/$YOURTARGET.wants`, and then symlink the additional services to enable into that directory.
The following is a mapping of SysVinit runlevels to _systemd_ targets.
[cols="2,5,5",options="header"]
.Runlevel to target mapping
|===
|Sysvinit Runlevel |systemd Target |Notes
|0 |runlevel0.target, poweroff.target |Halt the system.
|1, s, single |runlevel1.target, rescue.target |Single user mode.
|2, 4 |runlevel2.target, runlevel4.target, multi-user.target
|User-defined/Site-specific runlevels. By default, identical to 3.
|3 |runlevel3.target, multi-user.target |Multi-user, non-graphical.
Users can usually login via multiple consoles or via the network.
|5 |runlevel5.target, graphical.target |Multi-user, graphical. Usually
has all the services of runlevel 3 plus a graphical login.
|6 |runlevel6.target, reboot.target |Reboot
|emergency |emergency.target |Emergency shell
|===
== Mapping service commands
The following table demonstrates the _systemd_ equivalent of SysVinit commands.
NOTE: All recent versions of `systemctl` assume the `.service` suffix if left off the service name. For example, `systemctl start frobozz.service` is the same as `systemctl start frobozz`.
[cols=",,",options="header",]
|===
|Sysvinit Command |systemd Command |Notes
|`service frobozz start`|`systemctl start frobozz`|Used to start a service (not reboot persistent)
|`service frobozz stop`|`systemctl stop frobozz`|Used to stop a service (not reboot persistent)
|`service frobozz restart`|`systemctl restart frobozz`|Used to stop and then start a service
|`service frobozz reload`|`systemctl reload frobozz`|When supported, reloads the config file without interrupting pending operations.
|`service frobozz condrestart`|`systemctl condrestart frobozz`|Restarts if the service is already running.
|`service frobozz status`|`systemctl status frobozz`|Tells whether a service is currently running.
|`ls /etc/rc.d/init.d/`|`systemctl` or `systemctl list-unit-files --type=service` or +
`ls /lib/systemd/system/\*.service /etc/systemd/system/*.service`|Used to list the services that can be started or stopped +
Used to list all the services and other units
|`chkconfig frobozz on`|`systemctl enable frobozz`|Turn the service on, for start at next boot, or other trigger.
|`chkconfig frobozz off`|`systemctl disable frobozz`|Turn the service off for the next reboot, or any other trigger.
|`chkconfig frobozz`|`systemctl is-enabled frobozz`|Used to check whether a service is configured to start or not in the current environment.
|`chkconfig --list`|`systemctl list-unit-files --type=service` or `ls /etc/systemd/system/*.wants/`|Print a table of services that lists which runlevels each is configured on or off
|`chkconfig --list \| grep 5:on`|`systemctl list-dependencies graphical.target`|Print a table of services that will be started when booting into graphical mode
|`chkconfig frobozz --list`|`ls /etc/systemd/system/*.wants/frobozz.service`|Used to list what levels this service is configured on or off
|`chkconfig frobozz --add`|`systemctl daemon-reload`|Used when you create a new service file or modify any configuration
|===
NOTE: All `/sbin/service` and `/sbin/chkconfig` commands listed in the table continue to work on _systemd_-based systems and are translated to native equivalents as necessary. The only exception is `chkconfig --list`.
== Additional resources
* http://www.freedesktop.org/wiki/Software/systemd[Project homepage]
* http://0pointer.de/blog/[Lennart Poettering's blog] with lots of information about _systemd_. Lennart is the primary _systemd_ developer
* http://www.freedesktop.org/wiki/Software/systemd/FrequentlyAskedQuestions[freedesktop.org's _systemd_ FAQ]
* http://www.freedesktop.org/wiki/Software/systemd/TipsAndTricks[freedesktop.org's _systemd_ Tips & Tricks]
* http://fosdem.org/2011/interview/lennart-poettering.html[Interview with the developer]