daemontools - dependencies and runlevels

See Linux Boot Scripts from Richard Gooch for Reference why people care about replacing current init schemes.

See daemontools from D. J. Bernstein for another design for handling services on unix. A good strategy to learn daemontools' svscan, supervise and multilog features is to install djbdns as dns service on your system. You win supervised services (daemons) with a reliable process state and signal control, a reliable logging pipe that even logs through chroots, automatically rotated log files, and more ...

In contrary to Richard Gooch, I suggest not to implement service dependencies and runlevel handling in the Unix process no 1, /sbin/init, keep it small and simple, that is why I wrote the runit package, a minimal replacement for sysvinit using daemontools.

Read on if your are interested in how to bring up services in a specified order on system boot (dependencies) and emulate runlevels (telinit) with daemontools.

See also svscan as process 1 from Paul Jarc for replacing init and running svscan itself as process 1.


Service dependency

If you really have a service that needs another service up and running before starting, you can use the svwaitup program included in the runit package.

Add a line like this to the service's run script:

  #!/bin/sh
  svwaitup 3 /service/tinydns /service/dnscache || exit 1
  exec /example/service/startup
This will cause this service to start as soon as /service/tinydns and /service/dnscache were at least 3 seconds up and running.

For each service it depends on, add the corresponding service directory to the arguments of svwaitup.

Note that there is always a race condition, the service it depends on could die just in the moment it was 3 seconds up.

Runlevels

If you really need runlevels, here is an example script for switching to runlevel 3 running implicit selected services, telinit3.sh:
  #!/bin/sh
  ( cd /service
  for i in *; do
    case $i in

    # selected services:
    getty-tty1 |\
    tinydns |\
    dnscache |\
    sshd |\
    qmail-send |\
    qmail-smtpd )

      svc -u $i
      ;;
    # stop all others
    *)
      echo svc -d $i
      ;;
    esac
  done
  )
  exit 0
Your are free to define any numbers of runlevels and name them as you like.

Switching to the default runlevel is done by:

  #!/bin/sh
  ( cd /service
  for i in *; do
    if [ -e ${i}/down ]
      then svc -d $i
      else svc -u $i
    fi
  done
  )
  exit 0
Of cource this can be implemented more user friendly with some little efford and also the need(8) concept from Richard Gooch could be implemented in tools for adding and removing services (and automatically those they need(8)) to or from different profiles (runlevels); there is no need for including extra code for this in the process no 1.

What is a service?

On most unix systems there are one time initialization tasks, such as fsck and mount filesystems. On some unixes also network service will be initialized once. Generally other services or daemons are started by bootup scripts on system boot, some unix systems run sysvinit.

Having the above design in mind, why not think about eth0 as a service? Let a supervisor garantee the state of eth0, take it like any other service.

How about packet filter rules? Make it a service that is carefully watched, get notified on abnormal events using socklog's log event notification.

Finally you can make also those one time initialization tasks like fsck to services.


Gerrit Pape <pape@smarden.org>
$Id: noinit.html,v 1.4 2002/05/31 13:51:16 pape Exp $