Table of Contents

1 Regarding this document

  • Whenever we talk about some arbitrary "service" we will use the example name my_service. The common base directory for a service run through runit is then /etc/service/my_service/, e.g. /etc/service/spark-master holds the service which runs the spark-master.


Reference can be found here.

a UNIX process no 1
starts and monitors a service and optionally an appendant log service
starts and monitors a collection of runsv(8) processes
controls and manages services monitored by runsv(8)
continuously reads log data from the service's stdin, optionally filters log messages, and writes the data to one or more automatically rotated logs.
runs a program with a changed process state

Processes/services are created as follows:

  1. Create a directory under /etc/sv/, e.g. /etc/sv/my_service/, and create a symbolic link from this dir to /etc/service/my_service/.
    • Service directory must be in /etc/service/ for runsv to run it regularly and restart on shutdown, etc.
    • Any service directory added to /etc/service/ through creation or linking will be run by runsv within 5 seconds
    • In fact, normally services run by runsv would be located at /service/ but for some reason the image we use as a base in our docker setup uses /etc/service/ so we're going with that for now.
  2. Create a run script, e.g. /etc/service/my_service/run

    • Simply a normal bash script or any executable
    • Make sure it doesn't daemonize (i.e. runs in the background)
    • Make sure it's executable (chmod is your friend)
    • (Optional) Create a finish script which will run, well, when the service finishes, ergo when run process exits.
      • If run or finish exists right away, runsv will wait for a bit

    before restarting the service

    • When run OR finish finishes, the service will be restarted
    • unless my_service/down file exists, in which case no restart will occur
      • Important: because runsv will stdout to the logging-daemons stdin, we

    need to pipe stderr to stdout in /etc/service/my_service/run to make sure we get all the output of the service.

    exec 2>&1
    exec /usr/sbin/my_service
  3. (Optional) Create a logging directory, to which runsv will pipe the stderr of the service, e.g. /etc/service/my_service/log/
    • This directory follows almost all the same structure as the actual service dir,
      • Requires a run file which will receive the service's stderr on its stdin
      • Optionally can have a finish exec and so on
    • View logs and such using svlogd as mentioned above
    • A typical my_service/log/run will look something like this:

      exec svlogd -t /var/log/my_service/

      where the -t argument is simply to tell svlogd to add the timestamp at the beginning of each line.

  4. Control the process using sv command

3 Why runit ?

3.1 Service supervision

  • Each service has its own designated service-directory
  • Each daemon runs a child process of a supervising runsv process running in the corresponding service-directory
  • runsv command provides interface for signalling the service daemon and controlling the service and supervisor
  • Normally the sv command is used to send signals through this interface (runsv) and to query status information regarding the running service

3.2 Clean process state

  • runit guarantees each service a clean process state, no matter if the service is activated for the first time or automatically at boot time, reactivated, or simply restarted. Ergo, the service always started with the same:
    • environment
    • resource limits
    • open file descriptors
    • controlling terminals

3.3 Reliable logging

  • runsv provides a reliable logging facility for service daemon
  • If configured, runsv does the following:
    1. creates a pipe
    2. starts and supervises an additional log service
    3. redirects log daemon's stdin to read from the pipe
    4. service daemon's stdout to write to the pipe
  • This means that restarting the actual service does not require a restart of the log daemon, and vice versa
  • A very good choice for the log daemon is runit 's service logging daemon svlogd

3.4 Fast boot and shutdown

  • Services booted and shutdown in parallel
    • On startup: happens after the system's one-time tasks (stage 1)
    • On shutdown: stage 3 uses runit's control interface to wait until each service daemon is shutdown and system halt/reboot is initiated right after

4 runsv - starter and monitor

runsv service

The main thing is that runsv switches to the service directory and runs ./run. Further, it has a lot of conditional behavior:

4.1 Start and finish

  • ./run finishes and ./finish exists \(\rightarrow\) runsv starts ./finish
  • ./finish doesn't exist or finishes \(\rightarrow\) runsv restarts the service
  • ./run or ./finish exits immediately \(\rightarrow\) runsv waits a second before restarting

4.2 Control

runsv can be controlled in two ways:

  • use sv(8) (recommended)
  • write command characters straight to ./supervise/control (and optionally ./log/supervice/control )

For a full reference to the different controls, see here.

5 sv - controller and reporter

5.2 Description

The sv program reports the current status and controls the state of services monitored by the runsv(8) supervisor.

6 svlogd - log daemon

6.2 Description

  • svlogd continuously reads log data from its stdin, optionally filters log messages, and writes the data to one or more automatically rotated logs.
  • recent log-files can be processe automatically by an arbitrary program when they are rotated
  • svlogd can be told to alert selected log messages to stderr and through udp
  • svlogd runs until it sees EOF on stdin or sent a TERM signal

6.3 Log-directory

The log-dir called log contains the following:

  • some number of old log-files starting with @ , followed by a precise timestamp when the log-file was rotated out
  • current log-file with name current
  • the lock-file lock
  • maybe
    • state
    • newstate
  • optional
    • config

See the source for more information regarding the config file and such.