Jump to contentJump to page navigation: previous page [access key p]/next page [access key n]
documentation.suse.com / Setting Up a systemd Service

Setting Up a systemd Service

Publication Date: 04 Dec 2024
WHAT?

systemd is used to manage system settings and services. systemd organizes tasks into components called units and groups multiple units into targets.

WHY?

Learn about the basics of setting up a systemd service, including the types of services, editing and debugging systemd services and configuring e-mail notifications for failed systemd services.

EFFORT

It takes 20 minutes to read this article.

REQUIREMENTS
  • Basic understanding of Linux commands

  • Basic understanding of Linux processes, daemons, and control groups

1 What is systemd?

systemd is a system and service manager for Linux operating systems. It is the default initialization system for major Linux distributions. systemd is not directly initiated by the user, but installed through the /sbin/init and started during the early boot. systemd acts as the init system that brings up and maintains user space services when run as the first process on boot (PID 1). PID 1 is known as init and is the first Linux user-mode process created. It runs until the system shutdown.

systemd owns PID 1, and is started directly by the kernel. All other processes are started directly by systemd or one of its child processes. systemd mounts the host's file system and manages temporary files. It is backward compatible with the SysV init scripts. SysV is an initialization system that predates systemd.

In systemd, a unit is a resource that the system knows how to operate on and manage. This is the primary object that the systemd tools use. These resources are defined with configuration files called unit files.

systemctl is the central management tool for controlling the init system. It is used to examine and control the state of the systemd system and service manager.

Targets in systemd are groups of related units that act as synchronization points during a system boot. Target unit files have a .target file extension. Target units group together various systemd units through a chain of dependencies.

For troubleshooting, you can use journalctl, which is used to query and display log messages from the systemd journal.

For more information on systemd, you can refer to https://systemd.io and man 1 systemd.

2 Structure of a unit file

In systemd, a unit refers to any resource that the system knows how to operate on and manage. This is the primary object that the systemd tools use. These resources are defined using configuration files called unit files. Administration is easier when you understand unit files when working with systemd. Unit files use a simple declarative syntax that allows you to see easily the purpose and effects of a unit upon activation. Unit files have sections with directives, for example:

        [Section]
        Directive1=value
        Directive2=value
        . . .

Unit file types include the following sections:

[Unit]

The first section found in most unit files is the [Unit] section. This section is used to define the metadata of the unit file and configure the relationship of the unit file to other unit files. This section is usually placed at the top because it provides an overview of the unit file.

[Automount] / [Mount] / [Path] / [Service] / [Slice] / [Socket] /[Swap] / [Timer]

Sections containing directives that are specific to the respective type. See Section 3, “Unit file types” for a list of available types. Note that the types device, target, snapshot and scope do not have a type-specific section.

[Install]

This is often the last section in the unit file and is optional. This section is used to define the behavior of a unit file when it is enabled or disabled. When you enable a unit file, it automatically starts at boot. Based on the specific unit, there could be a dependency on other related units to work properly. For example, chrony requires the directives After, Wants, and Before, which are all dependencies for chrony to work with.

Example 1: A systemd service file
[Unit]
Description=usbguard 1

[Service]
ExecStart=/usr/sbin/usb-daemon 2

[Install]
WantedBy=multi-user.target 3

1

A brief and meaningful description explaining the service file's purpose.

2

Specifies the program to be executed when the service is started.

3

Starts a multi-user system with networking, and no graphical environment. This directive allows you to specify a dependency relationship.

3 Unit file types

You can determine the type of unit by its file extension. systemd categorizes units according to the type of resource they describe.

Types of unit files available for systemd:

.service

Describes how to manage a service or application. This includes how to start or stop the service, reload its configuration file (if applicable), under what conditions the service starts automatically, and the dependency or the hierarchy information for related unit files.

.scope

This unit file is automatically created by systemd from the information received from the D-Bus interface and is used to manage sets of system processes that are created externally.

.path

Defines a path for path-based activation. By default, a .service unit file of the same base name is activated. inotify is a kernel API that is used by programs that want to be notified about changes to files.

.snapshot

The systemctl snapshot command automatically creates a .snapshot unit file. This command creates temporary snapshots of the current state of the system. You can modify the current state of the system after making changes. Snapshots are used for rolling back temporary states.

.timer

Defines a timer that is managed by systemd. This is similar to a cron job for delayed or scheduled activation. A unit file with the same name, but with file extension .service is started when the timer is reached.

.slice

Associate Linux Control Group nodes, which allow resources to be assigned or restricted to any processes associated with the slice. The name indicates the hierarchy within the control group tree. Units are placed in slices by default depending on their type.

.target

Provides synchronization for other units during a boot up or a change in state, or brings the system to a new state. Other units specify their relation to targets in order to sync with the target's operations.

.socket

Describes a network, an IPC socket, or a FIFO buffer that systemd uses for socket-based activation. There is an associated .service file that starts when an activity is seen on the socket that this unit defines.

.device

Defines a device that has been designated for systemd management by udev or sysfs file system. Not all devices have the .device file. This unit file is required when ordering, mounting, or accessing a device.

.swap

Defines the swap space on the system. The name of the unit file must reflect the device or file path of the space.

.mount

Defines a mount point on the system to be managed by systemd. This file is named after the mount path, with the slashes changed to dashes. Entries within /etc/fstab can have units created automatically.

.automount

Defines a mount point that is automatically mounted. Name the file after the mount point that it refers to. A matching .mount unit file is required to define the specifics of the mount.

4 Unit dependencies and order

systemd has two types of dependencies: requirement and order dependencies. Requirement dependencies specify which other units must be either started or stopped when activating a unit. Order dependencies specify the order in which units must be started.

Unit dependencies

Unit files have the dependencies feature. A unit may want or require one or more other units before it can run. These dependencies are set in unit files with the directives Wants and Requires.

Wants

For example, if unit A has Wants=unit B, when unit A is run, unit B runs as well. But if unit B starts successfully or not, does not have an influence on unit A running successfully.

Requires

If unit A has Requires=unit B, both units run but if unit B does not run successfully, unit A is deactivated. It does not matter if the processes of unit A would have run successfully.

Unit order

Without proper instructions, systemd can run a group of units at the same time. Starting services in the right order is important for a good functioning of the Linux system. You can arrange the order with the unit file directives Before and After.

Before

For example, if unit A has Before=unit B, when both units are run, unit A is executed fully before unit B.

After

If unit A has After=unit B, when both units are run, unit B is executed fully before unit A.

5 Creating a Linux service with systemd

Create an auto-start task or program that executes every time that you boot or reboot your system by creating a Linux service with systemd.

Example 2: Automating task execution with systemd

Creating a custom systemd service, involves creating a service unit file, which defines the service and its behavior.

  1. Create a new script at the specified location, that is used by the systemd service:

    vi /usr/local/bin/FILE_NAME.sh

    The /usr/local/bin is the standard location for installing custom scripts and executables specific to the system. By placing the script in this location, you make it accessible to all system users without a need to specify the full path.

  2. Paste the following in the file:

    #!/bin/bash
         echo "Hello, Everyone!"
  3. Make the script executable:

    > sudo  chmod +x /usr/local/bin/FILE_NAME.sh
  4. Create a systemd unit file at the specified location:

    vi /etc/systemd/system/FILE_NAME.service
  5. Paste the following in the file:

    [Unit]
    Description= Name service
    
    [Service]
    ExecStart=/usr/local/bin/FILE_NAME.sh
    
    [Install]
    WantedBy=multi-user.target

    The Unit section gives you a description of the service. The Service section defines the service and its behavior. The ExecStart directive specifies the command to start the service. The Install section specifies when the service should start.

  6. Save and exit the file.

  7. To make systemd aware of the new service, run:

    > sudo  systemctl SERVICE_NAME
  8. Start,enable and check the status of the service:

    systemctl start SERVICE_NAME
    systemctl enable SERVICE_NAME
    systemctl status SERVICE_NAME

6 The sysctemctl edit command

You can use the systemctl command to edit and modify an existing service file.

There are three main directories where unit files are stored on the system:

/usr/lib/systemd/system/

When the RPM packages are installed, systemd unit files reside here.

/run/systemd/system/

systemd unit files created at run time. This directory takes precedence over the directory with installed service unit files.

/etc/systemd/system/

systemd unit files that are created by the systemctl enable command and also unit files added for extending a service. This directory takes precedence over the directory with unit files created at run time.

By default, the sysctemctl edit command opens a unit file snippet, for example:

> sudo  systemctl edit testhttp.service

This creates a blank file that is used to override or add directives to the unit file definition. A directory is created in /etc/systemd/system, which contains the name of the unit file with .d appended. For example, a directory called testhttp.service.d is created.

Within the directory, a snippet called override.conf is created. systemd merges the override snippet with the full unit file when the unit is loaded. This snippet's directives take precedence over those directives in the original unit file.

With the --full flag, you can edit the full unit file instead of creating a snippet. For example:

> sudo  systemctl edit --full testhttp.service

This loads the current unit file into the editor, allowing you to make modifications. When you save and exit the editor, the modified file is written to /etc/systemd/system, which takes precedence over the system's unit definition, usually located in /lib/systemd/system.

To remove any additions you have made, you can delete the unit's .d configuration directory or the the modified service file from /etc/systemd/system. After deleting the file or directory, reload the systemd process so that it reverts back to the initial system process.

7 Debugging a systemd service

Use the systemctl and journalctl commands to investigate the reasons for a failed system service.

When systemd fails to start a service, a generic error message is displayed, for example:

# systemctl start apache2
Job for apache2.service failed because the control process exited with error code.
See "systemctl status apache2.service" and "journalctl -xe" for details.
List all available services and their current status
# systemctl list-units -t service --all

For example:

# systemctl list-units -t service --all
  UNIT                                   LOAD      ACTIVE   SUB     DESCRIPTION>
  accounts-daemon.service                loaded    active   running Accounts Se>
  apache2.service                        loaded    failed   failed  The Apache HTTP server>
\u25cf acpid.service                     not-found inactive dead    acpid.servi>
 after-local.service                    loaded    inactive dead    /etc/init.d>
  alsa-restore.service                   loaded    active   exited  Save/Restor>
  alsa-state.service                     loaded    inactive dead    Manage Soun>
\u25cf amavis.service                    not-found inactive dead    amavis.serv>
  apparmor.service                       loaded    active   exited  Load AppArm>
  appstream-sync-cache.service           loaded    inactive dead    Synchronize>
  auditd.service                         loaded    active   running Security Au>
  augenrules.service                     loaded    active   exited  auditd rule>
Check whether a specific service has failed
# systemctl is-failed apache2.service
              failed
Check the status of the failed service
# systemctl status --full --lines=50 apache2
  ● apache2.service - Apache HTTP Server
  Loaded: loaded (/usr/lib/systemd/system/apache2.service; enabled; vendor preset: disabled)
  Active: failed (Result: exit-code) since Fri 2021-08-20 10:24:15 CEST; 2min 24s ago
    Docs: https://httpd.apache.org/docs
 Process: 2491 ExecStart=/usr/bin/apache2 --add-runtime oci=/usr/sbin/apache-runc $DOCKER_NETWORK_OPTIONS $DOCKER_OPTS >
Main PID: 2491 (code=exited, status=1/FAILURE)

In the above example, the service ran as process ID 2491, but failed. Error messages give you a hint on what to do.

Check the logs of the failed service
#  journalctl --catalog --pager-end --unit=apache2
[...]
  Aug 20 10:24:15 localhost.localdomain dockerd[2479]: unable to configure the Docker daemon with file /etc/apache2/daemon.json:
cannot unmarshal string into Go value of type map[string]interface {}

The option --unit limits the log entries only to the failed Apache2 service. The error message suggests looking into the file /etc/docker/daemon.json. In this scenario, the error was caused by a wrong syntax. You can fix this and restart the Apache2 service.

8 systemctl commands overview

The systemctl command is used to examine and control the state of systemd and service manager.

You can use the following common systemctl commands and refer to the man systemctl page.

8.1 Viewing systemd information

To view information about systemd components, you can use the following commands:

systemctl list-units

Lists the systemd units. You can use the optional arguments: --state=running to show the active units and --type=service to show the exited and active units.

systemctl list-unit-files

Lists the systemd units and the status, such as static, generated, disabled, alias, masked, and enabled.

systemctl list-dependencies

Lists the dependency tree.

systemctl list-dependencies UNIT_FILE

Lists the dependencies of a unit file.

8.2 Managing systemd services

The systemctl command enables you to perform the following tasks with services.

systemctl status SERVICE

Checks the status of the specific service.

systemctl show SERVICE

Displays the service information.

systemctl start SERVICE

Instead of manually starting the service, use the start command. When a change is made to the configuration file, the related service must be started again.

systemctl stop SERVICE

Stops a specific running service.

systemctl restart SERVICE

Instead of manually restarting the service, use the restart command. When a change is made to the configuration file, the related service must be restarted again.

systemctl enable SERVICE

Enables the service on boot.

systemctl disable SERVICE

Disables the service on boot.

systemctl reload-or-restart SERVICE

Reload the service if it supports reloading, otherwise it restarts the service. If the service is not running, it is restarted.

systemctl mask SERVICE

When a service is masked, this means the unit file is symlinked to /dev/null. A symlink for a masked service is created from /etc/systemd/system to point to /dev/null. This makes it impossible to load the service even if another enabled service requires it. It must be stopped manually, or it continues to run in the background. You can use --runtime option to only mask temporarily until the next reboot of the system.

Created symlink /etc/systemd/system/FOSSLinux.service → /dev/null.
systemctl unmask SERVICE

Unmasks the service. It is effective when the system is started or restarted manually.

8.3 Managing system states

The systemctl command enables you to perform power management processes on your system, like restarting, shutting down and so on, as described below.

systemctl reboot

Reboots the system reboot.target.

systemctl poweroff

Powers off the system poweroff.target.

systemctl emergency

Goes into the emergency mode emergency.target.

systemctl default

Goes back to default target multi-user.target.