Login With Github

Getting Started With Systemd In Practice

In the previous article, I introduced the main commands of Systemd. Today I will show you how to use it to complete some basic tasks.

1. Boot up

The configuration file will be added to the /usr/lib/systemd/system directory automatically when installing the software that supports Systemd.

If you want the software to be autostarted, you can execute the following command (take httpd.service as an example).

$ sudo systemctl enable httpd

The above command is equivalent to adding a symbolic link to the /etc/systemd/system directory, and pointing to the httpd.service file in /usr/lib/systemd/system.

This is because Systemd only executes the configuration files in the /etc/systemd/system directory when booting. So it means that if you put the modified configuration file in this directory, you can achieve the effect of overwriting the original configuration.

2. Start Service

After setting to autostart, the software will not start immediately and you must wait until the next boot. If you want to run the software now, you have to execute the systemctl start command.

$ sudo systemctl start httpd

After executing the above command, it may fail to start, so you should use the systemctl status command to check the status of the service.

$ sudo systemctl status httpd

httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled)
   Active: active (running) since 2014-12-05 12:18:22 JST; 7min ago
 Main PID: 4349 (httpd)
   Status: "Total requests: 1; Current requests/sec: 0; Current traffic:   0 B/sec"
   CGroup: /system.slice/httpd.service
           ├─4349 /usr/sbin/httpd -DFOREGROUND
           ├─4350 /usr/sbin/httpd -DFOREGROUND
           ├─4351 /usr/sbin/httpd -DFOREGROUND
           ├─4352 /usr/sbin/httpd -DFOREGROUND
           ├─4353 /usr/sbin/httpd -DFOREGROUND
           └─4354 /usr/sbin/httpd -DFOREGROUND

 05 12:18:22 localhost.localdomain systemd[1]: Starting The Apache HTTP Server...
 05 12:18:22 localhost.localdomain systemd[1]: Started The Apache HTTP Server.
 05 12:22:40 localhost.localdomain systemd[1]: Started The Apache HTTP Server.

The meanings for the above output results are as follows.

  • The Loaded line: the location of the configuration file; whether it is set to autostart
  • The Active line: indicate that it is running
  • The Main PID line: the main process ID
  • The Status line: The current state of the software provided by the application itself (here is httpd).
  • The CGroup block: all the child processes of the application
  • The log block: the logs of the application

3. Stop Service

To terminate a running service, you need to execute the systemctl stop command.

$ sudo systemctl stop httpd.service

Sometimes the command may not respond and the service will not stop. Then you have to "kill the process" and send a kill signal to the running process.

$ sudo systemctl kill httpd.service

In addition, you can execute the systemctl restart command to restart the service.

$ sudo systemctl restart httpd.service

4. Configuration Files

How a service is started is determined by its configuration files completely.

As mentioned earlier, the configuration files are mainly placed in the /usr/lib/systemd/system directory, and sometimes they may be in the /etc/systemd/system directory. Open the configuration file with a text editor.

The systemctl cat command can be used to view configuration files. Here I'll take the sshd.service file as an example: It's used to start an SSH server for other users to log in via SSH.

$ systemctl cat sshd.service

[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.service
Wants=sshd-keygen.service

[Service]
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
Type=simple
KillMode=process
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target

As you can see, the configuration file is divided into several blocks, each of which contains several key-value pairs.

Each of the blocks will be explained below.

5. [Unit] Block: Startup Order and Dependencies

The Description field of the Unit block gives a brief description for the current service, and the Documentation field gives the location of the document.

The next are the startup order and dependencies.

After field: It indicates that if network.target or sshd-keygen.service needs to be started, then sshd.service should be started after them.

Accordingly, there is a Before field that defines which services sshd.service should be started before.

Note that the After and Before fields only involve the startup sequence and do not involve dependencies.

For example, you want the web application to use a postgresql database to store data. In the configuration file, it is only defined to be started after postgresql, but is not defined to depend on postgresql. Then, when postgresql needs to be restarted for some reason, the web application will not be able to establish a database connection during the outage.

You need to use the Wants and Requires fields to set dependencies.

Wants field: It indicates that there is a "weak dependency" between sshd.service and sshd-keygen.service, which means that if "sshd-keygen.service" fails to start or stops running, it does not affect sshd.service to continue executing.

The Requires field indicates the "strong dependency", so if the service fails to start or exits abnormally, then sshd.service must also exit.

Note that the Wants field and the Requires field only involve dependencies, don't involve the startup order, and they will be started at the same time by default.

6. [Service] Block: Startup

The Service Block is used to define how to start the current service.

6.1 Startup command

Many softwares have their own environment configuration files, which can be read using the EnvironmentFile field.

EnvironmentFile field: It specifies the environment configuration file for the current service. The key=value inside the file can be obtained in the form of $key in the current configuration file.

In the above example, the environment configuration file for sshd is /etc/sysconfig/sshd.

The most important field in the configuration file is ExecStart.

ExecStart field: It defines the command to be executed when the process starts.

In the above example, it will execute the command /usr/sbin/sshd -D $OPTIONS when starting sshd, and the $OPTIONS variable comes from the environment parameter file specified by the EnvironmentFile field.

The following fields are similar to the role of the ExecStart field.

  • ExecReload field: The command executed when the service is restarted;
  • ExecStop field: The command executed when the service is stopped;
  • ExecStartPre field: The command executed before starting the service;
  • ExecStartPost field: The command executed after starting the service;
  • ExecStopPost field: The command executed after stopping the service.

Take a look at the example below.

[Service]
ExecStart=/bin/echo execstart1
ExecStart=
ExecStart=/bin/echo execstart2
ExecStartPost=/bin/echo post1
ExecStartPost=/bin/echo post2

In the above configuration file, the value of the second line ExecStart is set to null, which is equivalent to canceling the setting of the first line, so the result is as follows.

execstart2
post1
post2

You can add a hyphen (-) before all of the startup settings, and then it won't affect the execution of other commands when an error occurs. For example, EnvironmentFile=-/etc/sysconfig/sshd (note that there is a hyphen after the equal sign) means that no error will be thrown even if the /etc/sysconfig/sshd file does not exist.

6.2 Startup type

The Type field is used to define the startup type. The values ​​it can be set are as follows.

  • Simple (default): The process started by the ExecStart field is the main process.
  • Forking: The ExecStart field will be started in the way of fork(), and the parent process will exit and the child process will become the main process.
  • Oneshot: It's similar to simple, but it will be executed only once, and Systemd will wait for it to execute before starting other services.
  • Dbus: It's similar to simple, but it will wait for the D-Bus signal to start.
  • Notify: It's similar to simple; a notification signal will be sent after the startup, and then Systemd will start other services.
  • Idle: It's similar to simple, but the service will not start until all other tasks have been executed. It also can be used to let the output of the service not be mixed with the output of other services.

The following is an example of oneshot. When the laptop is booted, the touchpad should be turned off. So the configuration file can be written like this.

[Unit]
Description=Switch-off Touchpad

[Service]
Type=oneshot
ExecStart=/usr/bin/touchpad-off

[Install]
WantedBy=multi-user.target

The startup type of the above configuration file is set as oneshot, so it means that this service only needs to be run once and does not need to run for a long time.

If you want to open it sometime in the future, the configuration file can be modified as follows.

[Unit]
Description=Switch-off Touchpad

[Service]
Type=oneshot
ExecStart=/usr/bin/touchpad-off start
ExecStop=/usr/bin/touchpad-off stop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

The RemainAfterExit field is set to yes in the above configuration file, so the service will remain executing after the process exits. Then once the service is stopped through the systemctl stop command, the command specified by ExecStop will be executed, and the touchpad will be reopened.

6.3 Restart behavior

There are some fields which are in the Service block can be used to define the behavior for restarting.

KillMode field: It defines how Systemd stops the sshd service.

In the above example, setting KillMode to process means that only the main process is stopped, and no sshd child process is stopped. Thusthe SSH session opened by the child process remains being connected. The setting is less common, but it's important for sshd, otherwise you will kill it with your own open SSH session when you stop the service.

The values that can be set in the KillMode field are as follows.

  • control-group (default): All of the child processes in the current control group will be killed.
  • process: Kill the main process only.
  • mixed: The main process will receive the SIGTERM signal, and the child process will receive the SIGKILL signal.
  • none: No process will be killed, and it executes the stop command only.

What will be introduced next is the Restart field.

Restart field: It defines how Systemd restarts after sshd exits.

In the above example, Restart is set to on-failure, which means that any unexpected failure will result to restart sshd. If sshd stops normally (such as executing the systemctl stop command), it will not restart.

The values that can be set for the Restart field are as follows.

  • no (default): It will not restart after exiting.
  • on-success: It will restart when it exits normally (the exit status code is 0).
  • on-failure: It will restart when on abnormal exit (the exit status code is not 0), including signal termination and timeout.
  • on-abnormal: It will restart when it is terminated by a signal or timed out.
  • on-abort: It will restart when it receives a signal that is not captured.
  • on-watchdog: It will restart only when it exits for timeout.
  • always: It always restart regardless of the reason for the exit.

For daemons, it is recommended to set it to on-failure. For those services that allow to exit due to an error, you can set it to on-abnormal.

And the last one is the RestartSec field.

RestartSec field: It indicates the number of seconds that Systemd needs to wait before restarting the service. The above example is set to wait for 42 seconds.

7. [Install] Block

The Install block is used to define how to install the configuration file, which means how to boot.

WantedBy field: It indicates the Target where the service is located.

Target means a service group that represents a group of services. WantedBy=multi-user.target means that the Target where sshd is located is multi-user.target.

The setting is very important because when the systemctl enable sshd.service command is executed, a symbolic link to sshd.service is placed in the multi-user.target.wants subdirectory under the /etc/systemd/system directory.

There is a default startup Target for Systemd.

$ systemctl get-default
multi-user.target

The above result indicates that the default startup Target is multi-user.target. All services in this group will auto-boot. This is why the systemctl enable command can be used to set to run on start-up.

The systemctl list-dependencies command and the systemctl isolate command are also useful when using Target.

# View all the services included in multi-user.target
$ systemctl list-dependencies multi-user.target

# Switch to another target
# shutdown.target means the shutdown state
$ sudo systemctl isolate shutdown.target

In general, there are two common Targets: one is multi-user.target, which indicates the multi-user command line status; the other is graphical.target, which indicates the graphical user status, and it depends on multi-user.target. There is a Target dependency graph in the official documentation.

8. Configuration Files For Target

Target also has its own configuration files.

$ systemctl cat multi-user.target

[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes

Note that there is no startup command in the Target configuration file.

Here are the main fields in the above output.

  • Requires field: It requires basic.target to run together.
  • Conflicts field: If rescue.service or rescue.target is running, multi-user.target will not run, and vice versa.
  • After: It indicates that multi-user.target is started after basic.target, rescue.service, rescue.target, if they have been started.
  • AllowIsolate: It allows to switch to multi-user.target using the systemctl isolate command.

9. Restart After Modifying the Configuration File

After modifying the configuration file, you need to reload the configuration file and then restart the related service.

# Reload the configuration file
$ sudo systemctl daemon-reload

# Restart the related service
$ sudo systemctl restart foobar

0 Comment

temp