Using the Systemd service manager you can take advantage of some benefits, for example:
- automatic restart on failures
- an exit code/ reason
- the Systemd coredump handling
But to run Z-Way with the Systemd startup mechanism, several things need to be taken into account.
A simple working configuration file z-way-server.service for Z-Way:
# z-way-server.service: systemd service file
[Unit]
Description=Z-Way Server
[Service]
User=root
Group=root
Environment=PATH=/bin:/usr/bin:/sbin:/usr/sbin
WorkingDirectory=/opt/z-way-server
ExecStart=/opt/z-way-server/z-way-server
#Restart=always
#RestartSec=2min
[Install]
WantedBy=multi-user.target
This configuration file z-way-server.service
can be installed with the script ./install_systemd.bash.
For more information on the service unit configuration refer to the
Systemd Website
and to
Service unit configuration
- stop the z-way-server:
sudo /etc/init.d/z-way-server stop
don't delete the SysVinit script /etc/init.d/z-way-server ! - install the Systemd service file:
./install_systemd.bash
- start the z-way-server:
sudo systemctl enable z-way-server
sudo systemctl start z-way-server
Z-Way still uses the SysVinit start-stop mechanism in init.d. Especially the behavior on updates has to be considered:
- On update first it stops a running z-way-server process with
sudo /etc/init.d/z-way-server stop
- During the update it creates a new SysVinit script, but only if there isn't one.
- After update at last it starts the z-way-server with
sudo /etc/init.d/z-way-server start
Also it creates new runlevel-links for the configuration file.
If you would migrate to Systemd and simultaneously remove the SysVinit script, you would have to do some things manually on every update:
- Before update:
stop the running z-way-server process - After the update:
stop the z-way-server again
remove the SysVinit script again
start z-way-server with the systemd command
That's inconvenient. And it could cause problems if it's forgotten.
If both files, the Systemd service file and the SysVinit script, are present, the Systemd service always takes precedence and the SysVinit script is ignored, regardless of whether it is enabled or disabled (Systemd FAQ).
My own tests have confirmed this. The z-way-server is started only once at system boot, although all runlevel links for init.d are existing.
Of course, this only applies to system starts and system stops, not to manual calls. Invoking the SysVinit commands manually won't work properly together with Systemd.
To solve all the problems with concurrend execution described above, at last I came to the following modification in my SysVinit script:
...
SYSTEMD_CONFIG=/etc/systemd/system/$NAME.service
case "$1" in
start)
if [ -x "$RESETFILE" ]; then
"$RESETFILE" check_reset
fi
if [ -e "$SYSTEMD_CONFIG" ]
then
echo "sudo systemctl start $NAME.service"
sudo systemctl start $NAME.service
echo "sudo systemctl enable $NAME.service"
sudo systemctl enable $NAME.service >/dev/null 2>&1
else
echo -n "Starting z-way-server: "
start-stop-daemon --start --pidfile $PIDFILE --make-pidfile --background --no-close --chdir $DAEMON_PATH --exec $NAME > /dev/null 2>&1
echo "done."
fi
;;
stop)
if [ -e "$SYSTEMD_CONFIG" ]
then
echo "sudo systemctl disable $NAME.service"
sudo systemctl disable $NAME.service >/dev/null 2>&1
echo "sudo systemctl stop $NAME.service"
sudo systemctl stop $NAME.service
fi
if [ `pidof $NAME` ]
then
echo -n "Stopping z-way-server: "
start-stop-daemon --stop --quiet --pidfile $PIDFILE
rm -f $PIDFILE
echo "done."
fi
;;
...
If the Systemd service file doesn't exist, all SysV commands work as normal.
If the Systemd service file exists, start and stop are redirected to Systemd
commands.
An eventually declared automatic restart by Systemd is disabled after a manual stop.
This SysVinit script is stored with name config_z-way-server.replace and can be installed with the script ./install_init.d.bash.
This change will not be removed by Z-Way. Z-Way doesn't overwrite the SysVinit script with the updates.
This example enhances the above described solution for automatic restarts after failures, with an email notification and with an automatic examination of core dumps.
It consists of an enhanced Systemd service file, a bash script for the examination and a System service file for that bash script.
# z-way-server.service: systemd service file
[Unit]
Description=Z-Way Server
OnFailure=exam_coredump.service
[Service]
User=root
Group=root
Environment=PATH=/bin:/usr/bin:/sbin:/usr/sbin
WorkingDirectory=/opt/z-way-server
ExecStart=/opt/z-way-server/z-way-server
Restart=on-failure
RestartSec=2min
[Install]
WantedBy=multi-user.target
# exam_coredump.service: systemd configuration file
[Unit]
Description=call exam_coredump.bash after Z-Way Server failure
[Service]
User=root
Group=root
Type=oneshot
Environment=PATH=/bin:/usr/bin:/sbin:/usr/sbin
WorkingDirectory=/opt/z-way-server/automation/userModules/MxSystemd/sh
ExecStart=/opt/z-way-server/automation/userModules/MxSystemd/sh/exam_coredump.bash
[Install]
WantedBy=multi-user.target
- install 2 more shell packages, necessary for the core dump examination:
sudo apt install systemd-coredump
sudo apt install lz4
- choose the target folder where the results of the coredump examination shall be stored
- create a file named params by copying the file params_template and
enter the name of the target folder.
if you want to be notified with an email: create a file named emailAccount.cfg by copying the file emailAccount_template.cfg and enter your data. - stop the z-way-server:
sudo systemctl disable z-way-server
sudo systemctl stop z-way-server
- install the two Systemd service files:
./install_systemd.bash z-way-server.service.restart
./install_systemd.bash exam_coredump.service
- start the z-way-server:
sudo systemctl enable z-way-server
sudo systemctl start z-way-server
Note: The result files are stored with the current timestamp and are not removed automatically.
Note: The notification email is sent with a simple bash script. It does not work for email services that require special authentication (for example like Gmail).
The Raspberry Pi does not have a hardware clock. Normally this is not a problem. However, it is ugly if the timestamps are temporarily incorrect after a boot (e.g. in the log file).
The following method can be used to delay the start of z-way-server until time synchronization has been completed.
# z-way-server.service: systemd service file
[Unit]
Description=z-way-server.service: Z-Way
Wants=time-sync.target
After=time-sync.target
OnFailure=exam_coredump.service
[Service]
User=root
Group=root
Environment=PATH=/bin:/usr/bin:/sbin:/usr/sbin
WorkingDirectory=/opt/z-way-server
ExecStart=/opt/z-way-server/z-way-server
Restart=on-failure
RestartSec=2min
[Install]
WantedBy=multi-user.target
- check the state of the timesyncd service:
sudo systemctl status systemd-timesyncd.service --no-pager
timedatectl status
- install and start the timesyncd service, if not yet done:
sudo systemctl enable systemd-time-wait-sync.service
sudo systemctl start systemd-time-wait-sync.service
- replace the Systemd service file:
./install_systemd.bash z-way-server.service.timesync
Note: In file /etc/systemd/timesyncd.conf it's possible to define a local time server.
Note: Another time service software may have to be terminated and deactivated (e.g. ntp, chrony, ...).
systemctl status systemd-timesyncd.service --no-pager
timedatectl status
timedatectl timesync-status
timedatectl show-timesync