perpetrate(8)

NAME
perpetrate - supervise a persistent process and optional logger

SYNOPSIS
perpetrate [-hV] svdir

DESCRIPTION
perpetrate is called by perpd(8) to start and supervise a persistent process with an optional logger as defined by the files found in svdir.

On startup, perpetrate inspects the directory svdir. If the optional file named rc.log is present and executable, perpetrate spawns a child process to run it, setting up a pipe between its stdin and the stdout of the main service. To start the logging process, perpetrate invokes rc.log as follows:

    ./rc.log start svname

The first argument is the literal string ``start'', with the svname argument set to the basename of svdir.

After starting the optional logger, perpetrate proceeds to spawn a child process to run the required file named rc.main. If a logging process has been defined as described above, perpetrate will also connect the stdout of the main service to the stdin of the logger.

When starting the main service, perpetrate will invoke rc.main exactly as described for rc.log above:

    ./rc.main start svname

The files rc.main and rc.log are known as ``runscripts''. The result of running ``start'' on a runscript should normally be a persistent process, some long-running program designed to start at system boot and continue running until system shutdown. Runscript conventions and examples may be found in the perpetrate(5) manual.

perpetrate monitors its ``start'' processes to make sure they continue running. If it notices that one of these processes has terminated, it will attempt to reset and then restart it.

To reset a process that has terminated from ``start'', perpetrate will invoke its associated runscript again in either one of two forms, depending on whether the process exited normally, or was terminated by a signal:

    ./rc.main reset svname exit exitcode
or
    ./rc.main reset svname signal signum signame

The first argument in both cases is the literal string ``reset''. If the service exited normally, this is followed by the literal string ``exit'' and a string representation of the numeric exit code returned by the process. If the service was terminated by a signal, the ``reset'' is followed by the literal string ``signal'', a string representation of the numeric signal number that killed the process, and the symbolic name for the signal, such as SIGTERM.

A runscript process running ``reset'' will normally run to completion and return/exit promptly. After the resetting process terminates, perpetrate will then attempt to restart the service, invoking its runscript with the same ``start'' and svname arguments as described above.

To avoid chronic service failures from looping too quickly, perpetrate delays at least one second beyond the last ``start'' time before trying to restart a service.

While perpetrate monitors its services, it also maintains and publishes current status information for client utilities such as perpls(8) and perpstat(8). perpetrate also listens on a control interface for administrative control commands from utilities such as perpctl(8).

perpetrate will exit with failure immediately after startup under certain conditions. These include: being unable to find or change into the service directory; being unable to find or change or write certain control files; finding another instance of perpetrate running on the service directory; or being unable to create a pipe to the logging service. Otherwise, once perpetrate has started successfully, it is designed to run continuously until shutdown of the system.

  STARTUP MODIFICATION

The startup procedures for perpetrate as described above may be modified by installing certain specific ``flag'' files into the service directory.

If a file named flag.down is present, perpetrate will not attempt to start the rc.main control executable immediately at startup. In such cases, the perpctl(8) utility may be used to tell perpetrate to start the service at a later time.

If a file named flag.once is present, perpetrate will attempt to start the rc.main control executable immediately at startup, as usual, and then reset it if it terminates. But when the reset completes, perpetrate will not restart the main service. Again, the perpctl(8) utility may be used to tell perpetrate to restart the service if necessary, or to ``unflag'' its once setting.

If both files flag.down and flag.once are present when perpetrate is starting, the behavior described for flag.down takes precedence.

The existence of either of the flag files flag.down and flag.once only affects the behavior of perpetrate at startup. If they are installed in the service directory after an instance of perpetrate has already started and is running, they will have no effect until perpetrate itself is stopped and restarted.

The presence of either of these flag files also has no effect on the optional logging service. If a file named rc.log is present and executable at startup, perpetrate will attempt to start and supervise a logging service, irrespective of the presence of any of the flag files described above.

OPTIONS

-h  Help. Print a brief usage message to stderr and exit.

-V  Version. Print the program version to stderr and exit.

FILES
In the pathnames described below, let the name CWD refer to the directory from which perpetrate is started.

CWD/
    The startup directory for perpetrate. This will be the base directory for perpd(8), normally /etc/perp. After perpetrate inspects svdir and sets up its control files, it will continue to operate from this directory.

CWD/.control/<hash_svdir>/
    Each perpetrate instance creates and maintains certain runtime control files in a directory that shadows the service directory under its supervision. The path to this shadow directory is based on a required directory named .control found in the startup directory. The full path to the control directory is completed by a unique string representing the device/inode of svdir. (Note: normally .control will itself be configured as a symlink to a directory within the /var hierarchy.)

svdir/
    The service definition directory for this perpetrate instance, setup by perpd(8) as the first argument on the command line. In a normal installation, svdir will be a simple relative pathname, equivalent to its basename(1). perpetrate uses svdir as svname in its arguments to rc.main and rc.log, and to locate certain control files as described above. While perpetrate itself operates from CWD, the child processes spawned to execute rc.main and rc.log switch into svdir before calling the runscript.

svdir/rc.log
    Optional. Controls the logger for the main service. See perpetrate(5).

svdir/rc.main
    Required. Controls the main service. See perpetrate(5).

svdir/flag.down
    Optional. A ``flag'' file used to tell perpetrate to not start the main service on startup. May be zero length and created with the touch(1) command. A service flagged as down on startup may be brought up at a later time with the perpctl(8) utility.

svdir/flag.once
    Optional. A ``flag'' file used to tell perpetrate to run the main service (and reset it) only once, and not restart it. May be zero length and created with the touch(1) command. A service flagged as ``once'' on startup may be unflagged at a later time with the perpctl(8) utility.

ENVIRONMENT
PERP_BASE
    perpd(8) defines the variable PERP_BASE in the environment for each perpetrate supervisor it starts. This provides perpetrate(5) runscripts the means to access the base service directory as necessary. perpetrate itself does not interact with the PERP_BASE variable, however. Instead it relies on being started within the base service directory in which the subdirectory svdir is located.

ERROR LOGGING
perpetrate prints any of its own runtime diagnostics to the stderr file descriptor it inherits from perpd(8). In a normal installation, where perpd(8) is associated with a logging utility, the diagnostics for perpetrate will be captured by the logger for perpd(8).

SIGNALS
If perpetrate receives a TERM signal, it exits following a controlled shutdown of the services under its supervision. First it sends TERM and CONT signals to the main service and waits for it to terminate. It then runs rc.main ``reset'' and waits for that process to terminate. It then closes the stdin to the logging process and waits for it to terminate. It then runs rc.log ``reset'' and waits for that process to terminate. Then perpetrate itself exits 0.

AUTHOR
Wayne Marshall, http://b0llix.net/perp/

SEE ALSO
perp_intro(8), perpboot(8), perpctl(8), perpd(8), perpetrate(5), perphup(8), perpls(8), perpok(8), perpstat(8), sissylog(8), tinylog(8)