The s6-svscan program

s6-svscan starts and monitors a collection of s6-supervise processes, each of these processes monitoring a single service. It is designed to be either the root or a branch of a supervision tree.


     s6-svscan [ -S | -s ] [ -c max ] [ -t rescan ] [ scandir ]



s6-svscan always reacts to the following signals:

By default, it also reacts to the following signals:

But if the -s option was given, then instead of those default actions, s6-svscan uses configurable handlers: it forks and executes a program every time it receives one of the following signals.

If an action cannot be taken (the relevant file doesn't exist, or isn't executable, or any kind of error happens), s6-svscan prints a warning message to its standard error but does nothing else with the signal.

The -s mechanism is useful, for instance, when s6-svscan is running as process 1 and needs to trap signals such as SIGINT (sent on some systems by a Ctrl-Alt-Del press) in order to perform some specific work instead of executing into .s6-svscan/finish on the spot.

s6-svscan will not exit its loop on its own when it receives a signal such as SIGINT and the -s option has been given. To make it exit its loop, invoke a s6-svscanctl command from the signal handling script. For instance, a .s6-svscan/SIGINT script could look like this:

  #!/command/execlineb -P
  foreground { shutdown-the-services }
  s6-svscanctl -i .

The reaper

Upon receipt of a SIGCHLD, or a s6-svscanctl -z command, s6-svscan runs a reaper routine.

The reaper acknowledges (via some wait() function), without blocking, every terminated child of s6-svscan, even ones it does not know it has. This is especially important when s6-svscan is run as process 1.

If the dead child is a s6-supervise process watched by s6-svscan, and the last scan flagged that process as active, then it is restarted one second later.

The scanner

Every rescan milliseconds, or upon receipt of a SIGALRM or a s6-svscanctl -a command, s6-svscan runs a scanner routine.

The scanner scans the current directory for subdirectories (or symbolic links to directories), which must be service directories. It skips names starting with dots. It will not create services for more than max subdirectories.

For every new subdirectory dir it finds, the scanner spawns a s6-supervise process on it. If dir/log exists, it spawns a s6-supervise process on both dir and dir/log, and maintains a never-closing pipe from the service's stdout to the logger's stdin. This is starting the service, with or without a corresponding logger. Every service the scanner finds is flagged as "active".

The scanner remembers the services it found. If a service has been started in an earlier scan, but the current scan can't find the corresponding directory, the service is then flagged as inactive. No command is sent to stop inactive s6-supervise processes (unless the administrator uses s6-svscanctl -n), but inactive s6-supervise processes will not be restarted if they die.

Implementation notes