sortix-mirror/share/man/man7/daemon.7

114 lines
4.0 KiB
Groff

.Dd September 19, 2022
.Dt DAEMON 7
.Os
.Sh NAME
.Nm daemon
.Nd system background process
.Sh DESCRIPTION
A daemon is a system background process that performs a task or continuously
provides a service.
.Xr init 8
starts daemons on system startup per the
.Xr init 5
configuration and stops them on system shutdown.
.Pp
Conventions for daemons have varied between traditional init systems and this
document describes the modern design of daemons suitable for this operating
system.
Daemons should default to the behavior described below, or offer the behavior
through options if they need to be compatible with historic default behavior.
.Pp
A daemon is implemented as a system program, usually in
.Pa /sbin
inside the appropriate prefix,
whose name conventionally is the name of the service it implements plus the
letter d (as opposed to a client program).
Its runtime dependencies on other daemons are declared ahead of time in the
init system's configuration, so the daemons can be started in the right order.
.Pp
The process will be started per the init system's configuration with the
appropriate command line arguments, environment variables, working directory,
user, group, and so on.
.Pp
The process must remain in the foreground such that
.Xr init 8
can manage its lifetime.
It must not
.Xr fork 2
to become a background process and escape
the init system.
The process should have no need to escape the controlling terminal by starting a
new session using
.Xr setsid 2 .
Daemons should not write a pid file but instead be administered through the init
system.
.Pp
Logs should be written to the standard error as it is non-buffered and is meant
to contain messages that are not process output.
Alternatively logs may be written to the standard output.
The standard output may be the same file description as the standard error.
The standard input should not be used and will be
.Pa /dev/null .
The log entries should be formatted as plain line; or if the program wants to
supply additional meta data, one of the log formats described in
.Xr init 5
or the syslog format.
.Xr syslog 3
is discouraged but may be used if the program has additional meta data.
On this operating system,
.Xr syslog 3
will write the log entry to the standard error instead of sending it to a
centralized log service, which is unreliable on other operating systems.
Daemons should prefer letting the init system manage the log files but may
provide their own logging as appropriate.
.Pp
The process may be executed as root per the init system configuration.
Privileges should be dropped after acquiring the needed protected resources.
The main loop should run with the least privileges required, ideally as another
user, potentially in a
.Xr chroot 2
or sandboxed environment.
.Pp
Continuous daemons providing a service should signal their readiness once the
main loop is serving requests, such that the init system will start dependent
daemons.
Unfortunately there is no portable convention and this operating system uses the
.Ev READYFD
environment variable containing a file descriptor pointing to a writing pipe,
where the daemon must write a newline upon readiness.
Alternatively closing the pipe is considered readiness as a discouraged
fallback.
.Pp
The process must exit 0 if the daemon has concluded its work and exit non-zero
in the case of errors.
The daemon may be restarted by the init system
upon error per the configuration.
.Pp
The process must exit unconditionally when sent
.Dv SIGTERM
and should gracefully conclude its work immediately and recursively terminate
any child processes.
In this case, dying by the
.Dv SIGTERM
signal is considered a successful exit.
The process is killed with
.Dv SIGKILL
if it does not gracefully terminate within a high system-specific timeout.
.Sh EXAMPLES
A daemon can signal readiness using this utility function:
.Bd -literal -offset indent
static void ready(void) {
const char *readyfd_env = getenv("READYFD");
if ( !readyfd_env )
return;
int readyfd = atoi(readyfd_env);
char c = '\\n';
write(readyfd, &c, 1);
close(readyfd);
unsetenv("READYFD");
}
.Ed
.Sh SEE ALSO
.Xr init 5 ,
.Xr init 8