Month: January 2017

Supervising a Telldus Daemon

It is rare but sometimes it happens – the telldus daemon responsible for communicating with the Telldus Duo hardware has disappeared from the processlist, crashed or exited silently. This is not acceptable on an embedded system where processes shall have 100% uptime. The preferred way is to have some sort of supervisor which is responsible for restarting the process if it disappears.

Who is the naturally supervisor? Well, the process that started the process to be supervised. In Linux the first process started is either the old init or the newer systemd, which then starts all the other processes according to runlevels and dependencies (systemd) or sequence number (init/rc). There are a number of possible solutions for supervising using either init or systemd. A quick check on ‘google’ gives a couple of solutions, others probably exists as well:

  • daemontools – a supervisor which monitors processes, possible to use with init.
  • monit – a supervisor which monitors processes but also have a wealth of other monitoring possibility. Seems more targeted to server systems than embedded.
  • built in supervising in systemd – the systemd has a simple supervisor built in which restarts processes.
The websolution and the telldus daemon nowadays run on the raspbian called ‘Jessie’. Raspbian ‘Jessie’ has systemd as the first process that starts all other processes. The existing solution is built on init.d bash-scripts with links to the different runlevels (rcX). I decided to go with the systemd as the supervisor since it was time to transfer the init.d scripts to systemd services and only simple supervising was needed anyways.

In systemd you don’t write a script, instead you define a service having different properties and dependencies. This service configuration is put into /etc/systemd/system/<name>.service. The syntax is the same as .INI files on windows. See Service Configuration for details.

Telldus daemon as a systemd service

Explanations:

Type=forking

The telldus daemon is a forking daemon, i.e. it is forked off the starting process to be able to be automatically attached to the process having pid 1 (systemd in this case) making it independant of the terminal (tty).

 PIDfile=/var/run/telldusd.pid

The PID number is saved into this file when fork has been made, making it possible to find out the id of the process.

Restart=always

Always restart regardless the case abort, exception, signal or exit via return code.

Websolution (cherrypy) as a systemd service

Explanations:

After=network.target

Dependant on network connection before starting up.

Type=simple

Ordinary process i.e. doesn’t return if started since it is listening on network connections

User=root

Start process as root, since the webserver will switch to telldus user as soon as possible.
Environment=”PYTHONPATH=/usr/local/bin/setup”
Sets and exports the env. variable PYTHONPATH to the started process.

To make the services start call:

sudo systemctl enable telldusd
sudo systemctl enable cherrytelldus

Both solutions were tried out by killing the processes abruptly using ‘kill -kill ‘ and verified that they were restarted.

Advertisements