Systemd in short

Robert Crowther Apr 2022
Last Modified: Feb 2023

Guide.

Run guide

Basic,

systemctl start/stop serviceName

Restart is a process restart. Reload is, where possible, implemented as a configuration update. Faster, gentler,

systemctl restart/reload serviceName

Says, “Run this service at boot”,

systemctl Enable/Disable serviceName

Where?

For inspiration and information, system scripts go here,

/usr/lib/systemd/system

Your scripts go here,

 /etc/systemd/system

Make guide

Do you need to run from a script?

Systemd can run a basic command. It can’t run a complex commandline. Especially multiple commands. So, do you need to script the action? Ok, like this,

nano /usr/local/bin/talk.sh

then script your acrion,

#!/bin/sh
echo "Stoned me, to my soul"

Permissions,

chmod 755 /usr/local/bin/talk.sh

Try the script,

./usr/local/bin/jetty.sh

A start/stop service

Presuming startable/stoppable code with a commandline ‘rollit’, this,

nano /etc/systemd/system/rollit.service

Then,

# RollIt.service
[Unit]
Description=RollIt

[Service]
# Basic type of service, executes a process
Type=simple

# Process to execute
ExecStart=rollit -v

[Install]
# Attempt service start for boot
WantedBy=basic.target

Options

Only covers the most used options—theere are many more.

[Unit]

After=otherServiceNames

Run after these other units. No reliance on their success

Requires=ptherServiceNames.socket

Won’t run at all without these

Wants=otherServiceNames

Will run standalone, but if available will use, so try to run after (Ithink R.C.)

[Service]

ExecStartPre=

Do something before

ExecStop=

Do something to stop the action (if not a one‐off)

ExecReload=

Do something to reboot the action (or re‐read config) (if not a one‐off)

ExecStartPost=

Do something after

User=aUserName

Launch process under this user

WorkingDirectory

Move to this directory before executing

Restart=on‐failure

If encironment fails, attempt a restart

[Service] type=

simple

Command is the process/service

forking

A process that forks

oneshot

Expected to return command. If RemainAfterExit is added, then the service may have something ongoing. I’ve seen it used for network up, cleanup. hibernate rtc.

Two more options are for specific kinds of process ‘dbus’ and ‘notify’.

[Install]

(older word ’runtime’, but note that Systemd targets are not an exact match for the finer graded ‘runtimes) Systemd ‘target’ for timing of boot/device initialisation,

WantedBy=

Attempt start at this level

RequiredBy=

Must start at this level

Useful targets,

basic.target

System running

multi‐user.target

Multi‐user environment available, but may not be graphical

Also reboot.target, graphical.target, poweroff.target, rescue.target

Importance of the Install stanza

This is how you get a service auto‐running at boot time.

Start/Stop

If you want a service that can start/stop, Systemd says it would like you to write something with rock‐solid start/stop. However, Systemd will work ok without that. It’s your decision, me, I like to see code run.

Test

Test run,

systemctl status rollit

That should tell us if the service is loaded, but it will be disabled and dead. Try then look at log,

systemctl rollit.service
journalctl -S today -u rollit.service

Errors

Changed a config?

systemctl daemon-reload

Frequent. Almost always a permission problem. If connection to another device/service is the aim, try look at the service Systemd configuration in ‘/usr/lib/systemd/system’. Or track PIDs and to see how the service process runs. If access to the filesystem is the aim, look at the files and parent file permissions. Look out for a Systemd configuration PrivateTmp. Temporary files have become a source of security breaches, so Systemd treats them seriously. Sometimes service configurations create private tmp directories no other code can see,

Unable to access XXX

That log that talks errors and can’t be cleared can be trimmed,

journalctl -S today -u rollit.service

Happens all the time. Check the file is properly formed. More subtle, check file encoding. Systemd is modern, likes UTF8,

Assignment outside of section

A Timer

Needs a service unit to control the process. Then,

nano /etc/systemd/system/talk.timer
# talk.timer
[Unit]
Description=Schedule Talk

# Allow manual starts
RefuseManualStart=no

# Allow manual stops
RefuseManualStop=no

[Timer]
# Execute if missed a time
Persistent=false

# First time, run 120 seconds after boot
OnBootSec=120

# Run every 6 hours thereafter
OnUnitActiveSec=21600

# Do this
Unit=talk.service

# No run until device boot is finished
[Install]
WantedBy=timers.target

Test run,

# start the timer
systemctl start talk

Should be able to,

systemctl start|stop|restart talk

Options

[install]

TimeoutStartSec=

(not timing of the triggers) Duration in seconds for successfull start

TimeoutStopSec=

(not timing of triggers) Duration in seconds for successfull stop

RequiredBy=

WantedBy=

[Timer]

There is a calendar‐type directive, but it’s mush. If you can express in seconds, use them.

On Timeouts

Liking Systemd?

Many people disliked Systemd to the stage where it was forked out of operating systems. As a casual user, I ought to like it for solidity, separation of concerns and clean configuration. Systemd can do things ‘cron’ and variants can not—like remember to fire a timer if it misses a beat. But it’s messy, elaborate, and though the supplied documentation is comprehensive, the community support is pathetic. Also, the journal insists on logging errors, not found a way to clear it, so it is difficult to see if a service is acceptably configured or not.

Refs

Halfway useful discussion includes options,

https://linuxconfig.org/how-to-create-systemd-service-unit-in-linux

RedHat. They started this,

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/chap-managing_services_with_systemd

Feel less alone,

https://suckless.org/sucks/systemd/