For my sensor network I run a server process, which collects the data from several sensors. This is a sort of a daemon. In a first version it was started in a crontab with the time “@reboot”. But during the development I had to restart it every now and then: search the PID, kill it, start it in the background.
Isn’t there a better way? systemd to the rescue. In this first systemd post I will install a service file, so that the process can be started and stopped from the root account.
[Unit] Description=daemon for collecting sensor data After=network.target [Service] Environment=CONFIG=/home/maker/projects/sensors/sensors.cfg WorkingDirectory=/home/maker/projects/sensors ExecStart=/home/maker/projects/sensors/bin/sensor_collector Restart=always RestartSec=5 User=maker Group=maker [Install] WantedBy=multi-user.target
What is all this stuff?
[Unit] section: There is a
Description, which is an arbitrary text, and describes the daemon. And there is an
After keyword, which lists the required modules. In this case the daemon has to be started after the
network.target, because it needs the network.
[Service] section you give the information for the start of the daemon.
ExecStart is the program, which has to be started;
Group tell systemd the user and the group, under which the daemon runs.
Environment you can define some environment variables for the daemon. There can be several lines with the
Environment keyword. In the example above it’s the location of the configuration file – the program will read the value, and then uses this file. If the daemon needs a directory, where it runs, you give this with the keyword
WorkingDirectoy. And finally, if the daemon crashes, you can restart it with the keyword
Restart and the value
always. To give the system a little to (e.g. to cleanup the ports) give pause interval with
The last section
[Install] tells systemd in which runlevels the daemon will be used.
Now put the file into the directory
/etc/systemd/system. Let’s use the name
As root you can start, stop or check the status. The status is (of course) stopped at the moment:
# systemctl status sensor ● sensor.service - daemon for collecting sensor data Loaded: loaded (/etc/systemd/system/fill_bmp280.service; enabled) Active: inactive (dead) since Sun 2017-05-21 11:49:20 CEST; 2s ago Process: 588 ExecStart=/home/maker/projects/sensors/bin/sensor_collector (code=killed, signal=TERM) Main PID: 588 (code=killed, signal=TERM) Apr 14 12:17:45 lemath01 systemd: Started daemon for collecting sensor data. May 21 11:49:20 lemath01 systemd: Stopping daemon for collecting sensor data... May 21 11:49:20 lemath01 systemd: Stopped daemon for collecting sensor data.
Let’s start it and check the status again:
# systemctl start sensor # systemctl status sensor ● fill_bmp280.service - daemon for collecting sensor data Loaded: loaded (/etc/systemd/system/sensor.service; enabled) Active: active (running) since Sun 2017-05-21 11:49:28 CEST; 5s ago Main PID: 22741 (python3) CGroup: /system.slice/sensor.service └─22741 /usr/bin/python3 /home/maker/projects/sensors/bin/sensor_collector May 21 11:49:28 lemath01 systemd: Started daemon for collecting sensor data.
The last thing is to enable it for the reboot:
# systemctl enable sensor
And all is done. The daemon starts after reboot, and I can start and stop it every time. The only annoying thing, that I have to stop and stop it with
sudo or as root. But this will be another blog post.