SystemD Leviathan Part 2: Service Unit

Published on October 5, 2023 at 10:31 am by LEW


Since it is marketed as an init replacement, it is only fitting that we start with the systemd service unit. As this is what most users will deal with when managing services.

As was observed in the previous post, systemd can perform a wide range of tasks within an Operating System (OS) environment, beyond service management. Since services are the task that most users will interact with, it is logical to start there.

In future posts we will be exploring some of the other tasks that systemd can perform. Interestingly, many of these tasks are duplicated by other programs that perform said tasks much better. This goes back to one of the major complaints about systemd, bloat. And in point of fact, in many cases distributions do not make use of many of the installed systemd tasks, instead relying on other programs. This is one of the reasons I think systemd needs to be more modular.

Systemd Units

Before diving into services under systemd, we need to define what a unit is. To be as simplistic as possible, a systemd unit manages a task. A service is one of multiple different tasks types. Interestingly, task types can vary between OS’s. However there are a few common ones that are found across all environments, service being one of them.

The systemd unit consists of a name, type, configuration file, and corresponding components and programs found within the OS.

Systemctl Intro

The systemctl command is the main method for users to handling units in systemd. It should be noted that in most cases, when making changes, systemctl will require administrative access (root/su/sudo).

While our main focus will be on the service unit, it is appropriate to take a moment to examine the various tasks running on your system. I will be running the following commands on an Arch installation. As mentioned, your results may vary somewhat depending on your distribution.

If we use the systemctl command with the -t option and help, we get a list of the different types of units available on our system.

[rt@archer ~]$ systemctl -t help
Available unit types:

Next try running systemctl –all list-units | grep .service to list all service type units running currently on your system. The list will probably be fairly long.

Service Unit

A systemd service usually usually configures and maintains a daemon of some type running in the background. For example, dbus and getty are service units.

Configuration files for services are stored in a variety of locations on your system, so no hard and fast locations listed here for the systemd directory. Instead I suggest looking at the file locations used by the package. For example, I recently did some work with the minetest package, and looking at the file locations, determined that the service configuration file was stored at /usr/lib/systemd/system.

Generally speaking you will not be accessing these files unless you want to make changes, so there location is not of much interest to casual users. The system knows where they are and can find them.

Service unit configuration file names are usually [name].service. In many cases the service can be omitted, as the system is smart enough to figure out what you mean. If it does not work as expected, you might want to add it back in. For example, man-db.service (manual pages) can be entered as either man-db, or if that does not work then man-db.service.

Using Systemctl

Probably the most prevalent use of systemctl by the casual user will be to start, stop, enable, disable, and get status of services when needed. Lets work an example.

The man-db service was mentioned above, so lets take a look at it.

[rt@archer ~]$ systemctl status man-db
○ man-db.service - Daily man-db regeneration
     Loaded: loaded (/usr/lib/systemd/system/man-db.service; static)
     Active: inactive (dead)
TriggeredBy: ● man-db.timer
       Docs: man:mandb(8)

Anyone who has used systemV will immediately recognize that systemd provides a lot more information when querying a service status. From the above we can see that man-db is inactive, it is run daily to regenerate the manual database, it is controlled by a man-db.timer (another type of unit we will be exploring in a latter post), and there is a man page for it.

For another example, lets look at a minetest server (minetest is a free and open source alternative game engine for those not really satisfied with the direction Microsoft is taking mine craft).

[rt@archer ~]$ systemctl status minetest@minetest
● minetest@minetest.service - Minetest multiplayer 
server w/ minetest.conf server config
     Loaded: loaded (/usr/lib/systemd/system/
minetest@.service; enabled; preset: disabled)
     Active: active (running) since Thu 2023-10-05 07:29:39 
EDT; 15min ago
   Main PID: 307 (minetestserver)
      Tasks: 6 (limit: 4664)
     Memory: 324.5M
        CPU: 14.278s
     CGroup: /system.slice/system-minetest.slice/
             └─307 /usr/bin/minetestserver --config /etc/
minetest/minetest.conf --map-dir /var/lib/minetest/minetest/

Oct 05 07:29:39 archer minetestserver[307]: 2023-10-05 07:29:39: ACTION[Main]:
 [mcl_music] In-game music is activated
Oct 05 07:29:39 archer minetestserver[307]: 2023-10-05 07:29:39: ACTION[Main]:
 hb.register_hudbar: armor
Oct 05 07:29:42 archer minetestserver[307]:          __.               __.                 __.
Oct 05 07:29:42 archer minetestserver[307]:   _____ |__| ____   _____ /  |_  _____  _____ /  |_
Oct 05 07:29:42 archer minetestserver[307]:  /     \|  |/    \ /  __ \    _\/  __ \/   __>    _\
Oct 05 07:29:42 archer minetestserver[307]: |  Y Y  \  |   |  \   ___/|  | |   ___/\___  \|  |
Oct 05 07:29:42 archer minetestserver[307]: |__|_|  /  |___|  /\______>  |  \______>_____/|  |
Oct 05 07:29:42 archer minetestserver[307]:       \/ \/     \/         \/                  \/
Oct 05 07:29:42 archer minetestserver[307]: 2023-10-05 07:29:42: ACTION[Main]: World at
Oct 05 07:29:42 archer minetestserver[307]: 2023-10-05 07:29:42: ACTION[Main]: Server for
 gameid="mineclone2" listening on

This may look a little messy due to page size, but we can see that the server is running. And since it is running, we get some resource information about CPU,Memory, and PID. One note here, minetest is of the form name@.service. The @ sign indicates that the process is expecting a variable to be passed to it on startup. In our chase that was minetest.

Aside from getting the status, we can start, stop, enable, and disable services with the systemctl command. Just remember that in some cases, changing a service status may require administrative permission. Some example commands are given below for starting and stopping, and restarting.

sudo systemctl start minetest@minetest 
sudo systemctl restart minetest@minetest 
sudo systemctl stop minetest@minetest.service

This is particularly useful when doing configuration, as it is quicker to restart a service than to reboot a computer.

Enable and disable set what happens to a service at startup. If a service is enabled it will start at boot time.

sudo systemctl enable minetest@minetest
sudo systemctl disable minetest@minetest


In this post we have barley touched the surface of systemctl and systemd. We have learned how to control services (starting, stopping, enabling, etc). I plan to circle back around for a more in depth look at systemctl in a future post.

However at this point I want to continue exploring other options in the systemd suit. In the next post I plan to tackle timedatectl.

SystemD Leviathan Part 1: Overview

SystemD Leviathan Part 2: Service Units

SystemD Leviathan Part 3: Time Works

SystemD Leviathan Part4: Boot Loader

SystemD Leviathan Part 5: Networking

Add New Comment

Your email address will not be published. Required fields are marked *