| DAEMON(7) | daemon | DAEMON(7) |
.SH "NAME" daemon - Writing and packaging system daemons
.SH "DESCRIPTION"
.PP A daemon is a service process that runs in the background and supervises
the system or provides functionality to other processes. Traditionally,
daemons are implemented following a scheme originating in SysV Unix. Modern
daemons should follow a simpler yet more powerful scheme (here called
"new-style" daemons), as implemented by systemd(1). This
manual page covers both schemes, and in particular includes recommendations
for daemons that shall be included in the systemd init system.
.SS "SysV Daemons"
.PP When a traditional SysV daemon starts, it should execute the following
steps as part of the initialization. Note that these steps are unnecessary
for new-style daemons (see below), and should only be implemented if
compatibility with SysV is essential.
.PP The BSD daemon() function should not be used, as it implements
only a subset of these steps.
.PP A daemon that needs to provide compatibility with SysV systems should
implement the scheme pointed out above. However, it is recommended to make
this behavior optional and configurable via a command line argument to ease
debugging as well as to simplify integration into systems using systemd.
.SS "New-Style Daemons"
.PP Modern services for Linux should be implemented as new-style daemons.
This makes it easier to supervise and control them at runtime and simplifies
their implementation.
.PP For developing a new-style daemon, none of the initialization steps
recommended for SysV daemons need to be implemented. New-style init systems
such as systemd make all of them redundant. Moreover, since some of these
steps interfere with process monitoring, file descriptor passing, and other
functionality of the service manager, it is recommended not to execute them
when run as new-style service.
.PP Note that new-style init systems guarantee execution of daemon processes
in a clean process context: it is guaranteed that the environment block is
sanitized, that the signal handlers and mask is reset and that no left-over
file descriptors are passed. Daemons will be executed in their own session,
with standard input connected to /dev/null and standard output/error
connected to the systemd-journald.service(8) logging service, unless
otherwise configured. The umask is reset.
.PP It is recommended for new-style daemons to implement the following:
.PP These recommendations are similar but not identical to the Apple MacOS
X Daemon Requirements[2].
.SH "ACTIVATION"
.PP New-style init systems provide multiple additional mechanisms to activate
services, as detailed below. It is common that services are configured to be
activated via more than one mechanism at the same time. An example for
systemd: bluetoothd.service might get activated either when Bluetooth
hardware is plugged in, or when an application accesses its programming
interfaces via D-Bus. Or, a print server daemon might get activated when
traffic arrives at an IPP port, or when a printer is plugged in, or when a
file is queued in the printer spool directory. Even for services that are
intended to be started on system bootup unconditionally, it is a good idea
to implement some of the various activation schemes outlined below, in order
to maximize parallelization. If a daemon implements a D-Bus service or
listening socket, implementing the full bus and socket activation scheme
allows starting of the daemon with its clients in parallel (which speeds up
boot-up), since all its communication channels are established already, and
no request is lost because client requests will be queued by the bus system
(in case of D-Bus) or the kernel (in case of sockets) until the activation
is completed.
.SS "Activation on Boot"
.PP Old-style daemons are usually activated exclusively on boot (and manually
by the administrator) via SysV init scripts, as detailed in the LSB Linux
Standard Base Core Specification[1]. Among other issues, SysV init
scripts have the disadvantage of involving shell scripts in the boot
process. Support for init scripts has been phased out in modern Linux init
systems, and should not be relied upon. New-style init systems generally use
updated versions of activation, both during boot-up and during runtime and
using more minimal service description files.
.PP In systemd, if the developer or administrator wants to make sure that a
service or other unit is activated automatically on boot, it is recommended
to place a symlink to the unit file in the .wants/ directory of either
multi-user.target or graphical.target, which are normally used as boot
targets at system startup. See systemd.unit(5) for details about the
.wants/ directories, and systemd.special(7) for details about the two
boot targets.
.SS "Socket-Based Activation"
.PP In order to maximize the possible parallelization and robustness and
simplify configuration and development, it is recommended for all new-style
daemons that communicate via listening sockets to use socket-based
activation. In a socket-based activation scheme, the creation and binding of
the listening socket as primary communication channel of daemons to local
(and sometimes remote) clients is moved out of the daemon code and into the
service manager. Based on per-daemon configuration, the service manager
installs the sockets and then hands them off to the spawned process as soon
as the respective daemon is to be started. Optionally, activation of the
service can be delayed until the first inbound traffic arrives at the socket
to implement on-demand activation of daemons. However, the primary advantage
of this scheme is that all providers and all consumers of the sockets can be
started in parallel as soon as all sockets are established. In addition to
that, daemons can be restarted with losing only a minimal number of client
transactions, or even any client request at all (the latter is particularly
true for state-less protocols, such as DNS or syslog), because the socket
stays bound and accessible during the restart, and all requests are queued
while the daemon cannot process them.
.PP New-style daemons which support socket activation must be able to receive
their sockets from the service manager instead of creating and binding them
themselves. For details about the programming interfaces for this scheme
provided by systemd, see sd_listen_fds(3) and sd-daemon(3).
For details about porting existing daemons to socket-based activation, see
below. With minimal effort, it is possible to implement socket-based
activation in addition to traditional internal socket creation in the same
codebase in order to support both new-style and old-style init systems from
the same daemon binary.
.PP systemd implements socket-based activation via .socket units, which are
described in systemd.socket(5). When configuring socket units for
socket-based activation, it is essential that all listening sockets are
pulled in by the special target unit sockets.target. It is recommended to
place a WantedBy=sockets.target directive in the [Install] section to
automatically add such a dependency on installation of a socket unit. Unless
DefaultDependencies=no is set, the necessary ordering dependencies
are implicitly created for all socket units. For more information about
sockets.target, see systemd.special(7). It is not necessary or
recommended to place any additional dependencies on socket units (for
example from multi-user.target or suchlike) when one is installed in
sockets.target.
.SS "Bus-Based Activation"
.PP When the D-Bus IPC system is used for communication with clients,
new-style daemons should use bus activation so that they are automatically
activated when a client application accesses their IPC interfaces. This is
configured in D-Bus service files (not to be confused with systemd service
unit files!). To ensure that D-Bus uses systemd to start-up and maintain the
daemon, use the SystemdService= directive in these service files to
configure the matching systemd service for a D-Bus service. e.g.: For a
D-Bus service whose D-Bus activation file is named
org.freedesktop.RealtimeKit.service, make sure to set
SystemdService=rtkit-daemon.service in that file to bind it to the
systemd service rtkit-daemon.service. This is needed to make sure that the
daemon is started in a race-free fashion when activated via multiple
mechanisms simultaneously.
.SS "Device-Based Activation"
.PP Often, daemons that manage a particular type of hardware should be
activated only when the hardware of the respective kind is plugged in or
otherwise becomes available. In a new-style init system, it is possible to
bind activation to hardware plug/unplug events. In systemd, kernel devices
appearing in the sysfs/udev device tree can be exposed as units if they are
tagged with the string systemd. Like any other kind of unit, they may then
pull in other units when activated (i.e. plugged in) and thus implement
device-based activation. systemd dependencies may be encoded in the udev
database via the SYSTEMD_WANTS= property. See
systemd.device(5) for details. Often, it is nicer to pull in services
from devices only indirectly via dedicated targets. Example: Instead of
pulling in bluetoothd.service from all the various bluetooth dongles and
other hardware available, pull in bluetooth.target from them and
bluetoothd.service from that target. This provides for nicer abstraction and
gives administrators the option to enable bluetoothd.service via controlling
a bluetooth.target.wants/ symlink uniformly with a command like
enable of systemctl(1) instead of manipulating the udev
ruleset.
.SS "Path-Based Activation"
.PP Often, runtime of daemons processing spool files or directories (such as
a printing system) can be delayed until these file system objects change
state, or become non-empty. New-style init systems provide a way to bind
service activation to file system changes. systemd implements this scheme
via path-based activation configured in .path units, as outlined in
systemd.path(5).
.SS "Timer-Based Activation"
.PP Some daemons that implement clean-up jobs that are intended to be
executed in regular intervals benefit from timer-based activation. In
systemd, this is implemented via .timer units, as described in
systemd.timer(5).
.SS "Other Forms of Activation"
.PP Other forms of activation have been suggested and implemented in some
systems. However, there are often simpler or better alternatives, or they
can be put together of combinations of the schemes above. Example:
Sometimes, it appears useful to start daemons or .socket units when a
specific IP address is configured on a network interface, because network
sockets shall be bound to the address. However, an alternative to implement
this is by utilizing the Linux IP_FREEBIND/IPV6_FREEBIND
socket option, as accessible via FreeBind=yes in systemd socket files
(see systemd.socket(5) for details). This option, when enabled,
allows sockets to be bound to a non-local, not configured IP address, and
hence allows bindings to a particular IP address before it actually becomes
available, making such an explicit dependency to the configured address
redundant. Another often suggested trigger for service activation is low
system load. However, here too, a more convincing approach might be to make
proper use of features of the operating system, in particular, the CPU or
I/O scheduler of Linux. Instead of scheduling jobs from userspace based on
monitoring the OS scheduler, it is advisable to leave the scheduling of
processes to the OS scheduler itself. systemd provides fine-grained access
to the CPU and I/O schedulers. If a process executed by the service manager
shall not negatively impact the amount of CPU or I/O bandwidth available to
other processes, it should be configured with
CPUSchedulingPolicy=idle and/or IOSchedulingClass=idle.
Optionally, this may be combined with timer-based activation to schedule
background jobs during runtime and with minimal impact on the system, and
remove it from the boot phase itself.
.SH "INTEGRATION WITH SYSTEMD"
.SS "Writing systemd Unit Files"
.PP When writing systemd unit files, it is recommended to consider the
following suggestions:
.SS "Installing systemd Service Files"
.PP At the build installation time (e.g. make install during package
build), packages are recommended to install their systemd unit files in the
directory returned by pkg-config systemd
--variable=systemdsystemunitdir (for system services) or pkg-config
systemd --variable=systemduserunitdir (for user services). This will
make the services available in the system on explicit request but not
activate them automatically during boot. Optionally, during package
installation (e.g. rpm -i by the administrator), symlinks should be
created in the systemd configuration directories via the enable
command of the systemctl(1) tool to activate them automatically on
boot.
.PP Packages using autoconf(1) are recommended to use a configure
script excerpt like the following to determine the unit installation path
during source configuration:
PKG_PROG_PKG_CONFIG() AC_ARG_WITH([systemdsystemunitdir],
[AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files])],,
[with_systemdsystemunitdir=auto]) AS_IF([test "x$with_systemdsystemunitdir" = "xyes" -o "x$with_systemdsystemunitdir" = "xauto"], [
def_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
AS_IF([test "x$def_systemdsystemunitdir" = "x"],
[AS_IF([test "x$with_systemdsystemunitdir" = "xyes"],
[AC_MSG_ERROR([systemd support requested but pkg-config unable to query systemd package])])
with_systemdsystemunitdir=no],
[with_systemdsystemunitdir="$def_systemdsystemunitdir"])]) AS_IF([test "x$with_systemdsystemunitdir" != "xno"],
[AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])]) AM_CONDITIONAL([HAVE_SYSTEMD], [test "x$with_systemdsystemunitdir" != "xno"])
.PP This snippet allows automatic installation of the unit files on systemd
machines, and optionally allows their installation even on machines lacking
systemd. (Modification of this snippet for the user unit directory is left
as an exercise for the reader.)
.PP Additionally, to ensure that make distcheck continues to work, it
is recommended to add the following to the top-level Makefile.am file in
automake(1)-based projects:
AM_DISTCHECK_CONFIGURE_FLAGS = \
--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
.PP Finally, unit files should be installed in the system with an automake
excerpt like the following:
if HAVE_SYSTEMD systemdsystemunit_DATA = \
foobar.socket \
foobar.service endif
.PP In the rpm(8) .spec file, use snippets like the following to
enable/disable the service during installation/deinstallation. This makes
use of the RPM macros shipped along systemd. Consult the packaging
guidelines of your distribution for details and the equivalent for other
package managers.
.PP At the top of the file:
BuildRequires: systemd
%{?systemd_requires}
.PP And as scriptlets, further down:
%post %systemd_post foobar.service foobar.socket %preun %systemd_preun foobar.service foobar.socket %postun %systemd_postun
.PP If the service shall be restarted during upgrades, replace the %postun
scriptlet above with the following:
%postun %systemd_postun_with_restart foobar.service
.PP Note that %systemd_post and %systemd_preun expect the names of all units
that are installed/removed as arguments, separated by spaces.
%systemd_postun expects no arguments. %systemd_postun_with_restart expects
the units to restart as arguments.
.PP To facilitate upgrades from a package version that shipped only SysV init
scripts to a package version that ships both a SysV init script and a native
systemd service file, use a fragment like the following:
%triggerun -- foobar < 0.47.11-1 if /sbin/chkconfig --level 5 foobar ; then
/bin/systemctl --no-reload enable foobar.service foobar.socket >/dev/null 2>&1 || : fi
.PP Where 0.47.11-1 is the first package version that includes the native
unit file. This fragment will ensure that the first time the unit file is
installed, it will be enabled if and only if the SysV init script is
enabled, thus making sure that the enable status is not changed. Note that
chkconfig is a command specific to Fedora which can be used to check
whether a SysV init script is enabled. Other operating systems will have to
use different commands here.
.SH "PORTING EXISTING DAEMONS"
.PP Since new-style init systems such as systemd are compatible with
traditional SysV init systems, it is not strictly necessary to port existing
daemons to the new style. However, doing so offers additional functionality
to the daemons as well as simplifying integration into new-style init
systems.
.PP To port an existing SysV compatible daemon, the following steps are
recommended:
.SH "PLACING DAEMON DATA"
.PP It is recommended to follow the general guidelines for placing package
files, as discussed in file-hierarchy(7).
.SH "NOTES"
.PP All example codes in this page are licensed under MIT No Attribution
(SPDX-License-Identifier: MIT-0).
.SH "SEE ALSO"
.PP systemd(1), sd-daemon(3), sd_listen_fds(3),
sd_notify(3), daemon(3), systemd.service(5),
file-hierarchy(7)
NOTES
- 1.
- LSB recommendations for SysV init scripts
- 2.
- Apple MacOS X Daemon Requirements
| systemd 262.2 |