perpd(8)

NAME
perpd - persistent process scanner/supervisor/controller

SYNOPSIS
perpd [-hV] [-a secs ] [-g gid ] [ basedir ]

DESCRIPTION
perpd scans a directory to start and monitor a collection of services. It is the principal daemon of an active perp installation.

perpd operates on a base directory containing a set of perpetrate(5) service definitions. The base directory may be given by the basedir argument on the command line. If no basedir argument is given, perpd will look for a value associated with the environmental variable PERP_BASE. If neither of these is defined, perpd will operate on a compiled-in default directory, normally /etc/perp.

Service definitions are installed, configured and activated as subdirectories of the base directory. As perpd sequentially scans the base directory, it looks for subdirectory names not beginning with `.'. If perpd then finds the `sticky' bit set on the subdirectory, it considers the service definition ``active'' and attempts to start the service.

First perpd inspects the service subdirectory. If the optional file named rc.log is present and executable, perpd spawns a child process to run it, setting up a pipe to link its stdin to the stdout of the main service. To start the logging process, perpd 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 the subdirectory.

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

To start the main service, perpd invokes rc.main as follows:

    ./rc.main start svname

The conventions and arguments for starting rc.main are the same as those described for rc.log above.

perpd runs each child process for rc.main and rc.log in a new session and separate process group. The current working directory of the child process is set to the service subdirectory. The environment for each process is defined with the variable PERP_BASE set to the absolute path of the perpd base directory as described above.

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.

perpd monitors its ``start'' processes to make sure they continue running. If any active service process terminates, perpd is triggered to reset and restart the service.

To reset a process that has terminated from a ``start'', perpd will invoke the associated runscript again in either one of two forms, depending on whether the process exited normally, or was killed 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, perpd will then attempt to restart the service, again invoking its runscript with the same ``start'' and svname arguments as described above.

To avoid chronic service failures from looping too quickly, perpd will delay at least one second beyond the previous start time before trying to restart a service.

perpd may be triggered to immediately rescan the base directory with a SIGHUP signal or the perphup(8) command. perpd may also be configured at startup to automatically rescan the base directory at fixed intervals given by the -a option. For any new active service definitions found while scanning, perpd will attempt to start the service as described above. For any existing services whose subdirectory has been removed or is no longer sticky, perpd will bring down the service (terminating both the main and log processes, and then running ``reset'' on each), and remove the service from further active monitoring.

While perpd monitors its services, it also listens on a control interface for administrative commands and status requests from perp client applications such as perpctl(8), perpls(8), and perpstat(8).

perpd will exit failure immediately after startup under certain conditions: being unable to find or change into the base directory; finding another instance of perpd running on the same base directory; or failure during initialization of its control files. Otherwise, perpd is designed to start at system boot and continue running until system shutdown.

Normally a system is configured to start perpd as part of its init(8) sequence during system startup. The perp distribution includes a perpboot(8) utility, specifically designed to provide a reliable method for starting perpd under many different init(8) environments.

  STARTUP MODIFICATION

The service startup procedures described above may be modified by installing certain specific ``flag'' files into the service directory: flag.down and flag.once.

If a file named flag.down is present, perpd 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, perpd 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, perpd will not restart the main service. Again, the perpctl(8) utility may be used to tell perpd to restart the service if necessary, or to ``unflag'' its once setting.

If both files flag.down and flag.once are present when perpd is starting the service for the first time, 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 the service at activation. If they are installed in the service directory after perpd has already started and is running the service, they will have no effect until the service is deactivated and then reactivated.

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, perpd will attempt to start and monitor a logger for the service, irrespective of the presence of any of the flag files described above.

These flag files are usually of zero length and may be installed with the touch(1) command.

OPTIONS

-a secs
    Autoscan. Normally perpd runs in a quiet poll(2) state until some external signal or event causes it to rescan the base directory. The -a option may be used to set an interval that causes perpd to automatically rescan the base directory every secs seconds. For example, a secs argument of 5 will cause perpd to automatically rescan the base directory at least once every 5 seconds, imitating the behavior of daemontools svscan(8). An argument of 0 disables autoscanning.

-g gid
    Socket gid. Normally the control socket is created with the same ownership as the perpd process and with an explicit access mode 0700. The -g option sets the group ownership on the control socket according to the gid argument and changes the access mode on the socket to 0770. The gid argument may be given as either a numeric group id or as a group name. Note that the designated group will also require access to the .control directory (or related symlink) in which the control socket is installed.

-h  Help. Display a brief help message on stderr and exit.

-V  Version. Display the version string on stderr and exit.

EXAMPLES
perpd is designed to permit easy service activation/deactivation using the chmod(1) utility.

To activate a service within the perpd base directory, set the sticky bit of the subdirectory containing the service definition:

    chmod +t myservice && perphup

perpd will notice the service definition is now active and will initiate the startup procedures for it. Alternatively, the A command to perpctl(8) may be used instead to perform the equivalent activation:

    perpctl A myservice

To deactivate a service, unset the sticky bit:

    chmod -t myservice && perphup

perpd will notice the service has now been deactivated and will initiate a shutdown sequence on it. The X command to perpctl(8) may also be used to perform the equivalent deactivation:

    perpctl X myservice

Note that there is generally no need to use the perpctl(8) D command to bring down a service before deactivating it. Simply unsetting the sticky bit will bring the service down properly.

On some platforms/terminals, colorized ls(1) listings may be configured to display the `sticky' entries within a directory so they are readily visible. Othewise, request ls(1) to display a long listing format that presents directory permissions in the first column:

    # ls -l
    drwxr-xr-x  goodbye
    drwxr-xr-t  hello

In this truncated and contrived example, the service directory hello is active (has sticky bit set; see the `t' in its permission string), and the service directory goodbye is not active (sticky bit not set.)

The stat(1), perpstat(8), and perpls(8) utilities may also be used to display the active services within a directory.

FILES
/etc/perp
    The default base operating directory monitored by perpd, containing the set of service definition directories as described in perpetrate(5).

/PERP_BASE/.control
    perpd maintains associated runtime files and IPC interfaces within a subdirectory named .control. Normally this will be configured as a symbolic link to a directory within the /var hierarchy before starting perpd. For example, the symlink:

        .control -> /var/run/perp

    will cause perpd to maintain its runtime files under /var/run/perp. If perpd finds that .control is a dangling symlink on startup, it will attempt to make the directory that .control points to.

/PERP_BASE/.control/perpd.pid
    The lock file used by perpd to constrain execution to a single instance on a base directory. This file also contains the pid of the active perpd process.

/PERP_BASE/.control/perpd.sock
    The domain socket used by perpd to perform inter-process communications with perp client utilities such as perpctl(8) and perpls(8).

ENVIRONMENT
PERP_BASE
    The base scanning directory for the perpd process. If no basedir argument is given on the command-line at startup, perpd checks for a value defined with PERP_BASE. If this variable is not defined or empty, perpd uses a compiled-in default, usually /etc/perp. Irrespective of how basedir is determined at startup, perpd will use its value to define PERP_BASE within the environment of each service runscript it starts. If defined, PERP_BASE should be given as an absolute pathname.

PERP_SVPID
    The process ID of the active or terminated service. perpd supplies the process ID of the service process in the value of the PERP_SVPID variable within the environment of both the ``start'' and ``reset'' invocations of the runscript. In the case of the ``start'' target, the value given in PERP_SVPID is the process ID of the script itself, and which normally becomes the pid of the active service, as when the script calls the exec command to run the service program. In the case of the ``reset'' target, the value given in PERP_SVPID is the process ID of the service that has just terminated.

PERP_SVSECS
    The uptime in seconds of the terminated service. perpd supplies the total wallclock runtime of the process that has just terminated in the value of the PERP_SVSECS variable. This variable is defined only within the environment of the ``reset'' invocation of the runscript.

ERROR LOGGING
perpd emits diagnostics to stderr. To capture and log such messages, perpd will usually be started with an associated logger; see perpboot(8) for a utility designed to start perpd with an associated logger. In such an installation, the stderr of perpd will be redirected to stdout, and, in turn, its stdout will be piped to the stdin of the logger.

Each activated service starts with its stdout and stderr file descriptors inherited from perpd. If these are not subsequently redirected elsewhere, any diagnostics emitted by a service will also appear in the perpd logger.

SIGNALS
SIGHUP
    Triggers perpd to immediately rescan the base directory.

SIGTERM
    Triggers perpd to begin a shutdown sequence on each service process it is currently monitoring. After all service processes have terminated from their ``start'' and final ``reset'', perpd itself exits 0.

LIMITS
Each perpd instance can monitor a compile-time maximum number of active services, normally 200. The runtime environment of the perpd process should be configured to permit sufficient child processes (up to 2 per service), and open file descriptors (up to 3 per service, plus 7 requisite, plus a number for concurrent client connections, usually 20) to handle the actual number of services to be installed and activated. See getrlimit(2), runlimit(8) and the references to RLIMIT_NPROC and RLIMIT_NOFILE for more information.

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

SEE ALSO
chmod(1), perp_intro(8), perp-setup(8), perpboot(8), perpctl(8), perpetrate(5), perphup(8), perpls(8), perpok(8), perpstat(8), sissylog(8), tinylog(8)