Openrc-init and supervise-daemon

Openrc has developed itself and has gained some new features. In this article two features are highlighted:
 * Openrc-init, is openrc's own init system, and can act as a replacement for sysvinit, and
 * Supervise-daemon, which can supervise daemon processes. Supervise-daemon could replace start-stop-daemon, which is used by quite a few services.

Openrc-init
Replacing sysvinit with openrc-init takes a few steps. The description that follows refers to grub. Be aware that commands like, and are no longer working under openrc-init. Use, or instead.
 * Pass  on the kernel's commandline. Update  as follows:
 * Regenerate :
 * Make sure agetty processes for tty1 to tty6 will be started under openrc-init:
 * Reboot your system:

Supervise-daemon
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 (typcally 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.

Bringing a service under supervision theoretically should be as easy as adding  to its conf file in. It turns out to be a little more complex in some cases.

Openrc has the concept that services' startup code, the init files in can be adjusted through configuration files in. With this concept it is possible to add environment variables, or commandline options in the configuration file and not change the init file. Some init files however don't implemement this concept fully and define variables in the init file that cannot be adjusted in the conf file. Examples are: In such cases it might be needed to adjust the init file and not just the conf file.
 * defining a pidfile variable in an init file, e.g. in :
 * defining variables in the init file, rather then in the conf file, e.g. in :
 * not allowing for expansion of a variable, e.g. in :

Other cases that might need adjusting the init files are explicit references to the underlying utility s-s-d, which is not used in case of supervising.

agetty
agetty was already brought under supervise-daemon in the previous chapter. Verify with:

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:

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. Execute the following steps to bring it under supervision.

Stop the service:

Edit or create as follows:

Avahi-daemon's 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. Edit as follows:

Start the service back up:

Verify that the service is now supervised:

cupsd
Cups is the well known printing system of linux. Its daemon cupsd is provided by. The following steps will bring it under supervision:

Stop the service:

Create with the following content:

Remove the pidfile and s-s-d instructions from by commenting them out:

fcron
is a cron daemon implementation.

Stop the service:

Edit or create as follows:

Fcron's init file has an few references to s-s-d, defines command_args so that we cannot adjust it in, and it also has a pidfile instruction that needs to be removed. Last issue is that the init file does not honor any configuration option setting in the conf file.

Fix it by editting as follows:

Start the service:

And look at the pids to confirm that fcron is now under supervisor-daemon:

iwd
Iwd (iNet wireless daemon) is provided by and aims to replace. Take the following steps to bring iwd under supervision:

Stop the service:

Create :

Comment out  in  to avoid backgrounding by s-s-d:

Start the service back up:

Verify that it works as intended:

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 it's 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 supervise 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".
 * double 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.

First stop syslog-ng:

Edit as follows to make syslog-ng run onder supervise-daemon:

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:

Start syslog-ng again:

Verify that it works:

Notice that supervise-daemon is started with PID 10881, and syslog-ng with PID 10882, and PPID 10881, ie the supervise-daemon process.

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.

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

ntpd
The network time protocol daemon ntpd, provided by unfortunately cannot run in foreground.

vixie-cron
Gentoo's has no option to run in foreground, even though in other linux distributions the cron process would accept a -f flag. Consider an alternative like.

External resources

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