runit is Gerrit Pape's daemontools-inspired service supervision suite.

It's useful for running flakey daemons because you can make sure they get automatically restarted (with clean process state), and if you can get them to log to stdout or stderr, you can hand off the actual responsibilities of logging to a good logging daemon.

supervising silcd

silcd is the canonical implementation of a SILC server. Unfortunately, it occasionally has problems. You can have runit supervise it by setting up a service directory for it that looks like this:

[0 dirt:~]$ cat /etc/silc-server/servicedir/run
exec 2>&1
exec /usr/sbin/silcd -F
[0 dirt:~]$ cat /etc/silc-server/servicedir/log/run 
exec chpst -u silcdlogger svlogd -tt ./main
[0 dirt:~]$

You'll need to make sure a few things are in place:

  • both run and log/run must be executable
  • a user named silcdlogger must exist for the logger to use. It should have write privileges to /etc/silc-server/servicedir/log/main (i recommend giving it ownership to that subdir)
  • you'll need to make sure the runit package is installed, of course
  • to start silcd under runit supervision, just ln -s /etc/silc-server/servicedir /var/service/silcd and wait 5 seconds. Make sure you're not trying to simultaneously run silcd from other places as well (such as /etc/init.d/silc-server), of course! The two silcd processes would fight over access to the low-numbered port.

transitioning from sysvinit to runit

see runit/replaceinit.

transitioning from daemontools to runit

djb's daemontools is handy, but the licensing isn't as freely re-distributable as it might be.

In order to replace a daemontools installation on a debian system with a runit installation, dkg did a series of steps:

change /etc/inittab

the runit and daemontools packages both want to add a line tagged SV in /etc/inittab. That won't work, so if you already have daemontools installed, you'll need to modify the /etc/inittab line from daemontools to be named something other than SV. I'm not sure the best way to get init to see this change without rebooting without having two concurrently-running svscandir processes running at once, though.

When i've tried this, i just did a telinit q, and then killed/cleaned up the older svscandir process and its children, and hoped that the new process would start up the daemons correctly after that. This is rather too messy to be a good general solution. When you're trying to do this kind of cleanup on a system with a GNU userland, ps -eFH is a big help, because it will show you the process genealogy in a compact visual form (indentation).

install runit

aptitude install runit

install runit-dt

if you have any packages that explicitly Depend on daemontools (such as the package built by djbdns-installer), dpkg will likely complain if you were to remove the daemontools package. The quickest way around this is to use equivs to create a dummy package which Depends: runit, and Provides: daemontools.

Even better would be to make this shim package provide symlinks from each of /usr/bin/{setuidgid,envuidgid,envdir,softlimit,setlock} to chpst (see below).

change run and log/run files to use chpst instead of the analogous daemontools utilities

If you haven't made the symlinks for the daemontools utilities (mentioned above), you'll need to make the following change to run and log/run scripts:

Any existing servicedirs from any djb-authored packages will likely call the daemontools utilities. That means:

So, for example, the run files for a service directory created with dnscache-conf should look like this:

[0 dkg@ape dnscache]$ cat run
exec 2>&1
exec <seed
exec chpst -e ./env sh -c '
  exec chpst -U dnscache -o250 -d "$DATALIMIT" /usr/bin/dnscache
[0 dkg@ape dnscache]$ 

change log/run scripts to use svlogd instead of multilog

Similar to the above (but you can't work around it with symlinks, afaict):

Here's an example of that re-writing the log/run file for a service directory created with dnscache-conf looks like:

[0 dkg@ape dnscache]$ cat log/run 
exec chpst -u dnslog svlogd -t ./main
[0 dkg@ape dnscache]$ 

transfer services from /service (or /var/lib/svscan) to /var/service

the simplest thing would be to just break the daemontools-supervised symlinks, and create them in the runit-supervised directory.

for example:

rm /var/lib/svscan/tinydns
ln -s /etc/tinydns /var/service

In practice, i found this wasn't straightforward to do, because the old daemontools supervise process wanted to keep supervising even after the symlink was broken. I think the right thing might be something like:

rm /var/lib/svscan/tinydns
svc -d /etc/tinydns
svc -x /etc/tinydns
svc -d /etc/tinydns/log
svc -x /etc/tinydns/log
ln -s /etc/tinydns /var/service

uninstall daemontools

Now you should be able to uninstall the daemontools package cleanly without fear of breakage. If you've done anything more fancy with it, though (such as sophisticated multilog arguments, or odd things that chpst doesn't handle easily, you should obviously take more precautions.

aptitude purge daemontools

packages built in the runit style

This should perhaps be called "packages built in the daemontools style", since djb was the first wide-spread advocate of this simplified approach afaict.

Last modified 9 years ago Last modified on Dec 29, 2007, 2:56:15 PM