OpenRC/supervise-daemon

OpenRC-0.21 introduces its own daemon supervisor, supervise-daemon.

Introduction
OpenRC traditionally uses, often called s-s-d for starting, and stopping programs. When s-s-d starts a process it saves the process' PID somewhere on permanent storage (typically under ), and backgrounds (daemonizes) the process it started. When the time comes to stop, kill, or signal the daemon it uses the saved PID file to find the right process.

Supervising on the other hand usually keeps the started daemon as a child process of the supervisor. Backgrounding the daemon is therefore not needed, and not desired. An advantage of supervising a daemon is also that any terminal output sent to stdout and stderr can be caught by the supervisor, and sent to the system logger or to a file. Pidfiles are not needed because the supervisor process remembers the pid.

This article aims to provide help how to bring services under its supervision.

Instructions per service
The general recipe to bring a service under the control of supervise-daemon is to adapt its init file in as follows:
 * always add
 * remove any pidfile reference, e.g., or change   into
 * make sure the deamon will run in foreground:
 * if the daemon forks itself to the background (daemonizes itself) then pass the appropriate daemon command line option, e.g. . Note that the command line option to prevent daemonizing is different per service, and some services might not even provide this option.
 * if there is a statement like  then remove it
 * remove calls to and if needed replace them with calls to   as appropriate.

Currently, standard Gentoo init files do not use process supervision with supervise-daemon yet: it is left to users to make these modifications to the init files. What follows is a number of examples for different services / daemons.

acpid
Reviewing the man page of reveals:
 * .. will run as background process ..
 * .. -f, --foreground .. keeps acpid in the foreground by not forking at startup, and makes it log to stderr instead of syslog.

Edit as follows to make acpid run under supervise-daemon:
 * add the supervisor definition
 * add the arguments to make acpid run in foreground
 * rewrite the s-s-d command to a supervisor-daemon command

At the top of the file:

At the end of the file:

Start up the service:

Verify if acpid is now running under supervise-daemon:

Check the logs as well:

And when you create an acpid event, it will be logged:

Lastly, check if supervise-daemon will restart acpid when it terminates:

Notice the different PID.

avahi-daemon
contains a service avahi-daemon for service discovery. Its init file does not make use of s-s-d, but calls the binary  directly and gives it the instruction to daemonize:   on startup. This can be simply adjusted by defining the command variable as, and removing the start and stop functions from the file. Of course it is also needed to specify the supervisor.

Edit as follows:

Start the service back up:

Verify that the service is now supervised:

bluetoothd
provides Bluetooth services. The recipe to bring it under supervise-daemon is as follows:


 * remove the pidfile reference
 * remove the background instruction
 * define the supervisor

Edit as follows:

cupsd
CUPS is the well known printing system of Linux. Its daemon cupsd is provided by.

Remove the pidfile and s-s-d instructions from by commenting them out, and add the supervisor declaration to bring it under supervision:

cups-browsed
Cups-browsed is a daemon for  browsing  the  Bonjour  broadcasts of shared, remote CUPS printers.

Bring it under supervision by removing the background instruction and declaring the supervisor:

dbus-daemon
D-Bus is a message bus system, a simple way for applications to talk to one another. It can be brought under supervise-daemon like any other service.

Edit as follows:

dhcpcd
DHCPCD, the Dynamic Host Configuration Protocol Client Daemon is a popular DHCP client capable of handling both IPv4 and IPv6 configurations.

Take the following steps to have it run under supervise daemon:


 * remove the pidfile defintion
 * define the supervisor
 * pass the dhcpcd process option  to prevent it from backgrounding.

Edit as follows:

dnsmasq
Dnsmasq, provided by package, is a lightweight DHCP and caching DNS server. Dnsmasq's init file contains references to s-s-d, and pidfiles. The daemon needs to be configured to run in foreground.

Edit as follows:

fcron
is a cron daemon implementation. To get it supervised it is needed to:


 * remove the s-s-d references,
 * remove the pidfile declaration,
 * define the supervisor
 * tell the supervisor how to get the daemon to run in foreground
 * change the reload function to use supervise-daemon instead of s-s-d.

Edit as follows:

iwd
iwd (iNet wireless daemon) is provided by and aims to replace. Remove the backgrounding instruction and define the supervisor to bring iwd under supervision:

Edit as follows:

ntpd
The network time protocol daemon ntpd, from package can be brought under supervision by editing the init file to:


 * remove the pidfile references,
 * prevent forking to background by adding "-n" to the command line to of the ntpd daemon,
 * remove the s-s-d instruction,
 * define the supervisor.

rngd
Rngd is the daemon belonging to. It is meant to check and feed random data from a hardware device to the kernel random device.

Edit to bring it under supervision as follows:

sshd
sshd (Secure Shell Daemon) does not have a specific commandline option to run in foreground, instead it is needed to use the  debug option. There may be some more text logged.

Edit at the beginning of the file as follows:

All the way at the bottom of the file there is the reload function in which the s-s-d instruction should be changed to a supervise-daemon instruction:

syslog-ng
is an interesting case. Without any change, running syslog-ng under s-s-d it looks like this:

There is a process with in this case PID 7800 'supervising syslog-ng' with a parent-PID (PPID) of 1, which means its parent is the init process. There is also the process with PID 7802, which looks more like what we might expect, referencing the binary. This process' PPID is 7800, i.e. the supervising process.

The supervising syslog-ng process is actually also the same binary of syslog-ng:

Syslog-ng appears to be supervising itself. What it does after startup is:

If and when "supervise syslog-ng" detects that it's worker process (PID 7802) has terminated it will restart it. Syslog-ng calls this process mode "safe-background".
 * fork, to become a background daemon process (PID 7800) and get it to be adopted by the init process (PID 1);
 * fork again to create the worker process (PID 7802) as it's child process;
 * rename the process (PID 7800) to "supervise syslog-ng", in the parent process, and supervise its child (PID 7802).

In order to get syslog-ng to work well under supervise-daemon it needs to run in the foreground though. There are two commandline options that will make that happen  and.

With the standard init scripts syslog-ng writes a pid file. This interferes with the operation of supervise-daemon so will have to be removed. Edit to remove the --pidfile option in the command_args, and comment out the pidfile variable:

At the end of the file, the reload function needs to be changed to use the supervisor instead of s-s-d:

vixie-cron
The cron implementation offered by can be brought under supervision by editing  to remove the pid instruction, and pass it -n to make it run in foreground:

Services which won't run under a supervisor
Unfortunately not all services are easy to run under supervisor-daemon, or other supervisors. The requirement that the daemon needs to run in foreground is not satisfied with all daemons, or it simply does not work. Sometimes there are alternatives available.

One shot services
Some of the scripts in that are started by OpenRC, do not start daemons. Instead they run a program that terminates when it has performed its function, or they do a configuration setting.

Examples of such, with the action at boot / shutdown, are:
 * alsasound: loads / saves volume settings for audio
 * localmount: mounts / unmounts file systems as per
 * loopback: creates the loopback interface
 * swap: activates / deactivates swap devices
 * urandom: loads random seed and initializes / saves random seed
 * zram-init: creates / destroys zram devices.

There is no need to run such services under a supervisor.

netifrc
The default Gentoo networking scripts belonging to call s-s-d from under the hood. The scripts can start/stop services like dhcpcd, dhclient, pppd, wpa_supplicant when needed, and they use s-s-d for it.

dcron
version 4.5-r1 crashes without an error message when it is run under a supervisor. Consider an alternative like.

Tips 'n tricks
A system under openrc-init and supervise-daemon behaves a little different. This chapter shows some of the differences and how to take advantage of it.

rc-status
rc-status shows the time when supervised services were started, and the number of restarts:

Note the line for sshd, which shows that it was recently restarted by its supervisor. With only supervised services are displayed.

External resources

 * Mistakes to avoid when designing Unix dæmon programs
 * How to make daemons that will maximize sysadmin hatred