Glue Logic LLC logo

daemontools

The daemontools package provides a suite of utilities to reliably and securely start, run, log, and control server programs known as daemons. Dan Bernstein, the author of daemontools, explains the rationale behind daemontools quite well.

(This page assumes familiarity with daemontools. Please refer to links below for an introduction.)

compiling daemontools

Official source: http://cr.yp.to/daemontools.html
Install instructions: http://cr.yp.to/daemontools/install.html

Lots of information is available at http://thedjbway.org/daemontools.html, including some daemontools patches that are useful in any daemontools installation -- specifically the daemontools sigq12.patch. Also useful is the daemontools errno.patch which is required for compilation on many modern systems. The errno.patch is included in the daemontools logging patch below.

In addition to the sigq12.patch, we have patched daemontools to "chew its own bubblegum" so that svscan employs the same logging framework that it provides to services that are run under supervise.

The daemontools logging.patch directs svscan output through multilog or other logger which supervise monitors. With this patch, if a directory (or symlink to a directory) named /service/.svscan exists, then svscan will direct its stdout and stderr to the supervised service run from the /service/.svscan/log/ directory. This simplifies svscan startup scripts and replaces the use of readproctitle given in djb's examples, which does not work on some platforms, e.g. FreeBSD 5.1 notes thedjbway.org in booting svscan. Redirecting svscan output through multilog also provides a much better solution than other svscan startup scripts which direct output exclusively to console, causing problems to go undetected for a long time if the server is in a closet somewhere and nobody looks at console.

our favorite way to boot svscan

We split services into two groups, those local services that should always run -- such as local DNS resolver and local MTA/antivirus/antispam -- and those public networked services that should run only when the server is in full production (all the time, of course!). These include SSH, web, MTA on public IP addresses, IMAP, POP, authoritative DNS, etc. The /usr/local/service-local/ and /usr/local/service-public/ directories both contain symlinks to appropriate service directories in /var/service/ including the symlinks
   /usr/local/service-local/.svscan -> /var/service/svscan-local
   /usr/local/service-public/.svscan -> /var/service/svscan-public
and those target directories each have a log/ subdirectory that runs multilog. The output of any service that does not have its own log/ subdirectory will end up in these logs if the service does not redirect its output elsewhere.

Our /etc/inittab contains the following:

SL:2345:respawn:/usr/local/sbin/svscan.rc start /usr/local/service-local
SP:345:respawn:/usr/local/sbin/svscan.rc start /usr/local/service-public

SY:S0126:once:/usr/local/sbin/svscan.rc stop  /usr/local/service-public
SZ:S016:once:/usr/local/sbin/svscan.rc stop  /usr/local/service-local
For best results, at least the SY and SZ lines should be above the system initialization lines that run /etc/rcX scripts, but below rc.sysinit, if those scripts are run from your /etc/inittab. The SL and SP lines that start local and public services can be elsewhere, and might be after the /etc/rc* scripts are run, since the /etc/rc* scripts are typically where items such as networking interfaces are configured.

/usr/local/sbin/svscan.rc is just as straightforward. It takes a "start" or "stop" argument and an optional service directory, with the default being /service. First, the supervisors for the loggers are set to exit when the loggers exit. Then, the services are shut down and their supervisors are told to exit, at which point the loggers will read EOF and will themselves exit along with their supervisors. This sequence ensures that log entries will not be lost when the services and their loggers are shut down. Note that for this to succeed, svscan must not be running. If it is, it must be killed prior to running this script, or else svscan will simply respawn the services and their supervisors. The runlevel commands in /etc/inittab above take care of that for us. (Note that if a logger dies during the shutdown, it will not be restarted, and so some log entries may be lost, but this is still better than svc -dx /service/* /service/*/log.)

#!/bin/sh

PATH=/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin
SERVICES=${2:-"/service"}

exec </dev/null >/dev/null 2>&1

for log_dir in "$SERVICES"/*/log "$SERVICES"/.svscan/log; do
    if [ -d "$log_dir" ] \
       && svok "$log_dir" \
       && svstat "$log_dir" | grep -q ": up"
    then
        svc -ox "$log_dir"
    fi
done

svc -dx "$SERVICES"/*

[ "$1" = "start" ] && exec env - PATH=$PATH svscan "$SERVICES"

While the svscan.rc above is short and sweet, the script can be extended to do more than just svc -dx. For example, the script could check for a $SERVICES/*/shutdown script in each service directory, and if present, run the shutdown script. Such a svscan.rc script might look like this (untested):

#!/bin/sh

PATH=/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin
SERVICES=${2:-"/service"}

exec </dev/null >/dev/null 2>&1

for log_dir in "$SERVICES"/*/log "$SERVICES"/.svscan/log; do
    if [ -d "$log_dir" ] \
       && svok "$log_dir" \
       && svstat "$log_dir" | grep -q ": up"
    then
        svc -ox "$log_dir"
    fi
done

for service_dir in "$SERVICES"/*; do
    if [ -d "$service_dir" ] \
       && svok "$service_dir" \
       && svstat "$service_dir" | grep -q ": up"
    then
        [ -x "$service_dir"/shutdown ] && "$service_dir"/shutdown
        svc -dx "$service_dir"
    fi
done

[ "$1" = "start" ] && exec env - PATH=$PATH svscan "$SERVICES"

using daemontools

Running services under daemontools is quite easy, though some programs need a few tweaks or settings to keep them in the foreground or to direct their logs to where multilog can handle them. daemontools service examples contains a few such programs and provides the scripts we use to run them.


Home    |    Projects    |    Contact Us
© 2004 Glue Logic LLC