Skip to content

supervise.8

Manvendra Bhangui edited this page Apr 1, 2024 · 11 revisions

NAME

supervise - starts and monitors a service.

SYNOPSIS

supervise s [parent_ident]

DESCRIPTION

supervise(8) switches to the directory named s and starts ./init if it exists. It restarts ./init if ./init exits with non-zero status. It pauses for 60 seconds after starting ./init, so that it does not loop too quickly in case ./init exits immediately. s has to be relative to the current working directory and cannot start with the dot (.) or the slash (/) character. parent_ident is passed as a command line argument by svscan(8) when starting supervise log process when s/log exists. This is useful when listing supervised log processes using the ps(1) command.

After ./init exits with zero exit status, supervise starts ./run. It restarts ./run if ./run exits. It pauses for a second after starting ./run, so that it does not loop too quickly in case ./run exits immediately. supervise expects ./run to run in the foreground. Sometimes daemon fork themselves into background, which some consider bad software design. If you want to monitor such a daemon, set the sticky bit on ./run. This makes supervise go into subreaper mode using prctl(2) PR_SET_CHILD_SUBREAPER on Linux or procctl(2) PROC_REAP_ACQUIRE on FreeBSD. In subpreaper mode or when the environment variable SETPGID is set, ./run will have it's process Group ID set to the value of it's PID. Setting the process Group ID is required to monitor ./run reliably when ./run has a command which double forks. It is also required in such cases to make svc(8) command operate and control supervise reliably such double forked daemon/commands in ./run.

If the file s/down exists, supervise(8) does not start ./run immediately. You can use svc(8) to start ./run or to give other commands to supervise(8). supervise uses s/supervise/control fifo to read these commands.

On receipt of SIGTERM, supervise sends SIGTERM followed by SIGCONT to its child. It uses killpg(3) to send the signal if runnning in supreaper mode or when SETPGID environment variable is set. It uses kill(2) to send signals when not running in subreaper mod and SETPGID environment variable is not set. supervise requires to SIGTERM signals to get terminated when started by svscan(8) running as PID 1.

if the file s/shutdown exists supervise(8) executes shutdown when asked to exit. The pid of the process that exited is passed as the first argument to shutdown.

if the file s/alert exists supervise(8) executes alert whenever run exits. The pid of the process that exited is passed as the first argument to alert. The exit value or signal (if killed by signal) is passed as the second argument to alert. The third argument is either of the strings exited or stopped / signalled.

The last argument to ./run, ./shutdown and ./alert is the full path of s.

If the directory run/svscan exists, supervise(8) creates the directory s/supervise in run/svscan where run is either /run or /var/run tmpfs filesystem (depending on your operating system). The directory run/svscan is created by svscan(8) when DISABLE_RUN isn't set. supervise(8) maintains status information in a binary format in the directory s/supervise. The directory s must be writable to supervise(8). The status information can be read by svstat(8).

supervise(8) may exit immediately after startup if it cannot find the files it needs in s or if another copy of supervise(8) is already running in s. Once supervise(8) is successfully running, it will not exit unless it is killed or specifically asked to exit. On a successful startup supervise(8) opens the fifo s/supervise/ok in O_RDONLY|O_NDELAY mode. You can use svok(8) to check whether supervise(8) is successfully running. You can use svscan(8) to reliably start a collection of supervise(8) processes. svscan mirrors the service directory in /run or /var/run directory (whichever is found first). So /run/s will be analogous to /service/s. When started by svscan, error messages printed by supervise(8) will go the standard error output of svscan(8) process.

supervise(8) can wait for another service by having a file named s/wait. This file has two lines. The first line is time t in seconds and the second line is service name w. w refers to the service which service s should wait t secs after service w starts up. The amount of time t is limited to a max of 32767 secs. Any value above this value will be limited to 60 secs. supervise(8) opens w/supervise/up in write mode. If service w is up, the write returns immediately. If service w is down, write will block till w is up and running. If service w doesn't have supervise running, supervise will wait for 60 seconds before opening for write the file w/supervise/up again. The default value of 60 seconds gets overriden by the SCANINTERVAL environment variable used by svscan(8). If service w doesn't exist, s/wait will be ignored.

supervise(8) creates the following FIFOs for with O_RDONLY|O_NDELAY mode. See open(2) for description of O_RDONLY, O_NDELAY

  • s/supervise/control - for reading commands from clients like svc(8).

  • s/supervise/ok - clients can open this in write mode (O_WRONLY) to test if supervise(8) is running in s. If write returns, it means supervise(8) is running.

  • s/supervise/up - clients can open this in write mode (O_WRONLY) to test if service s is up. Any client that opens this fifo will block until the service s is up. If write returns, it means service s is running.

supervise logs informational, warning and error messages to descriptor 2. Informational messages can be turned on by setting the environment variable VERBOSE. Warning messages can be turned off by setting the environment variable SILENT. If you are using svscan for service startup, as setup for indimail-mta, you can set environment variables for supervise in /service/.svscan/variables directory.

SEE ALSO

svc(8), svok(8), svstat(8), svps(1), svscanboot(8), svscan(8), svctool(8), minisvc(8), readproctitle(8), fghack(8), pgrphack(8), multilog(8), tai64n(8), tai64nlocal(8), setuidgid(8), envuidgid(8), envdir(8), softlimit(8), setlock(8), open(2)

Clone this wiki locally