s6
Software
skarnet.org
The s6-supervise program
s6-supervise monitors a long-lived process (or service), making sure it
stays alive, sending notifications to registered processes when it dies, and
providing an interface to control its state. s6-supervise is designed to be the
last non-leaf branch of a supervision tree, the supervised process
being a leaf.
Interface
s6-supervise servicedir
- s6-supervise switches to the servicedir
service directory.
- It exits 100 if another s6-supervise process is already monitoring this service.
- If the ./event fifodir does not exist,
s6-supervise creates it and allows subscriptions to it from processes having the same
effective group id as the s6-supervise process.
If it already exists, it uses it as is, without modifying the subscription rights.
- It sends a 's' event to ./event.
- If the default service state is up, s6-supervise spawns ./run.
- s6-supervise sends a 'u' event to ./event whenever it
successfully spawns ./run.
- When ./run dies, s6-supervise sends a 'd' event to ./event.
- When ./run dies, s6-supervise spawns ./finish if it exists.
- ./finish must exit in less than 5 seconds. If it takes more than that,
s6-supervise kills it.
- When ./finish dies, s6-supervise restarts ./run unless it has been
told not to.
- There is a minimum 1-second delay between two ./run spawns, to avoid busylooping
if ./run exits too quickly.
- When killed or asked to exit, it waits for the service to go down one last time, then
sends a 'x' event to ./event before exiting 0.
Signals
s6-supervise reacts to the following signals:
- SIGTERM: bring down the service and exit, as if a
s6-svc -xd command had been received
- SIGHUP: exit as soon as the service stops, as if a
s6-svc -x command had been received
- SIGQUIT: currently like SIGTERM, but this might change in the future
Usage notes
- s6-supervise is a long-lived process. It normally runs forever, from the system's
boot scripts, until shutdown time; it should not be killed or told to exit. If you have
no use for a service, just turn it off; the s6-supervise process does not hurt.
- Even in boot scripts, s6-supervise should normally not be run directly. It's
better to have a collection of service directories in a
single scan directory, and just run
s6-svscan on that scan directory. s6-svscan will spawn
the necessary s6-supervise processes, and will also take care of logged services.
- You can use s6-svc to send commands to the s6-supervise
process; mostly to change the service state and send signals to the monitored
process.
- You can use s6-svok to check whether s6-supervise
is successfully running.
- You can use s6-svstat to check the status of a
service.
- s6-supervise maintains internal information inside the ./supervise
subdirectory of servicedir. servicedir itself can be read-only,
but both servicedir/supervise and servicedir/event
need to be read-write.
- The ./finish script is not guaranteed to have stdin and
stdout pointing to the same locations as the ./run script. More
precisely: the stdin and stdout will be preserved for ./finish
until s6-supervise is asked to exit, but the last ./finish
execution will have its stdin and stdout redirected to /dev/null.
(This is to avoid maintaining open descriptors when a service is down, which
would prevent its logger from exiting cleanly.)
Implementation notes
- s6-supervise tries its best to stay alive and running despite possible
system call failures. It will write to its standard error everytime it encounters a
problem. However, unlike s6-svscan, it will not go out
of its way to stay alive; if it encounters an unsolvable situation, it will just
die.
- Unlike other "supervise" implementations, s6-supervise is a fully asynchronous
state machine. That means that it can read and process commands at any time, even
when the machine is in trouble (full process table, for instance).
- s6-supervise does not use malloc(). That means it will never leak
memory. However, s6-supervise uses opendir(), and most opendir()
implementations internally use heap memory - so unfortunately, it's impossible to
guarantee that s6-supervise does not use heap memory at all.
- s6-supervise has been carefully designed so every instance maintains as little
data as possible, so it uses a very small
amount of non-sharable memory. It is not a problem to have several
dozens of s6-supervise processes, even on constrained systems: resource consumption
will be negligible.