-
Notifications
You must be signed in to change notification settings - Fork 0
Installation on the Raspberry Pi
When installing the System_Watchdog Daemon as a service we let it run as the user pi. Since the daemon might have to execute all manners of commands as the user root, we need to be able to use the command sudo
, an elegant solution of Raspbian (and Unix in general) to support the needed privilege elevation
The necessary prerequisite is that the user pi can execute sudo
without entering a password. This is the case in a normal Raspbian installation, but may not be the case in yours. To test it, enter the following command:
sudo ls
If this works without requesting a password, then everything is fine.
If the system requests a password, then we have to reconfigure it to work without that. Check the file /etc/sudoers.d/010_pi-nopasswd
. In a default Raspbian installation it should contain the following:
pi ALL=(ALL) NOPASSWD: ALL
Using the command sudo visudo /etc/sudoers.d/010_pi-nopasswd
you can change this to:
#pi ALL=(ALL) NOPASSWD: ALL
pi ALL=(ALL) NOPASSWD: /sbin/shutdown
Please be very! careful when editing this file, because if this file contains errors you cannot use sudo
anymore.
The daemon is written in Python 3. Python 2 is deprecated and using it no longer makes any sense.
A modern Raspbian installation should have all necessary Python 3 packages, so there should be no need to install additional packages.
Put the daemon files into a directory. The unit file references /opt/system_watchdog, so either use this or change the unit file. Install the unit as a system service, enable and start it. Check logs.
- Download the files in this repository to your Raspberry Pi.
- Create a directory /opt/system_watchdog/ as user root
sudo mkdir /opt/system_watchdog
- Change the owner of this directory to user pi
sudo chown pi /opt/system_watchdog
- Place everything in the directory /opt/system_watchdog as the user pi.
- Change the execution flag of the daemon:
chmod +x /opt/system_watchdog/system_watchdog.py
- Review the entries in the configuration file system_watchdog.cfg.
- Copy, as superuser, the service file to /etc/systemd/system/:
sudo cp system_watchdog.service /etc/systemd/system/
- Enable the service:
sudo systemctl enable system_watchdog
- Check the result:
sudo systemctl status system_watchdog
- Start the service:
sudo systemctl start system_watchdog
- Check the log for irregularities:
journalctl -r -u system_watchdog
- Every sleep time seconds the daemon should write a log entry
Writing a daemon today is simple work, all the heavy lifting is done by our trusty systemd (which today is prevalent on most Linux systems).
Systemd takes a description file for a service (called a unit) that contains all necessary information for starting, restarting and stopping the service and uses this to guarantee that the service is run according to our wishes.
Our unit file describes a very simple service that should be started very early after booting, but only after e.g., the syslog becomes available. So we start our description of the service with the name, the default dependencies (none), when to start (after the sysinit.target has been reached).
[Unit]
Description=SystemWatchdog Daemon
DefaultDependencies=no
After=multi-user.target
StartLimitIntervalSec=0
The final line is pretty important for our use case. Normally, when a service fails and systemd tries to restart it, it uses start rate limiting to ensure that the system is not overload by it trying to restart a service. But when the rate limit is exceeded, the service is no longer restarted at all. And this behavior can be turned off by setting the value of StartLimitIntervalSec
to the value 0.
The service description contains the specifics of how to start our service. The service type we choose is simple, which means that the service is available simply after starting the executable referenced after ExecStart
.
The next step is to define the restart characteristics for our service. We want to restart always (even if the daemon exits without a set return code) and want it to restart after one second pause.
And finally we want the daemon to run as user pi.
[Service]
Type=simple
ExecStart=/opt/system_watchdog/system_watchdog.py
Restart=always
RestartSec=1
User=pi
Until now we have described the prerequisites for and the specifics of the service. But until now we do not define that systemd should actually start the service at all. This is done by the last part of our service definition that states that we want the service to be started by the sysinit.target. This is used by systemd when we enable as service to decide when and how to start it.
[Install]
WantedBy=multi-user.target
And this is it. Naturally, systemd offers a lot more flexibility and complexity than shown here, but as shown it can be very simple to define a service with it and thus a system daemon for Linux.
You still need to execute the commands given before, but now it should be clear what happens behind the scenes.