X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=man%2Fdaemon.xml;h=853b3bb814790d6b3a35ad4c449b78ad7ee3e87f;hp=1cddf38f74374e6bda3bc0f0d1fa359b6cfdd1fb;hb=03fae01822b5275a2940458f65644796283a8a23;hpb=436c44a5d64ef136ead64e9b03c8c05cc573a61b diff --git a/man/daemon.xml b/man/daemon.xml index 1cddf38f7..853b3bb81 100644 --- a/man/daemon.xml +++ b/man/daemon.xml @@ -21,7 +21,7 @@ along with systemd; If not, see . --> - + daemon @@ -55,8 +55,9 @@ 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. + yet more powerful scheme (here called "new-style" + daemons), as implemented by + systemd1. SysV Daemons @@ -64,7 +65,7 @@ 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, + steps are unnecessary for new-style daemons (see below), and should only be implemented if compatibility with SysV is essential. @@ -80,7 +81,7 @@ /proc/self/fd, with a fallback of iterating from file descriptor 3 to the value returned by - getrlimit() for + getrlimit() for RLIMIT_NOFILE. Reset all signal @@ -91,23 +92,30 @@ SIG_DFL. Reset the signal mask - using sigprocmask(). + using + sigprocmask(). - Call fork(), + Sanitize the + environment block, removing or + resetting environment variables that + might negatively impact daemon + runtime. + + Call fork(), to create a background process. In the child, call - setsid() to detach from any terminal - and create an independent - session. + setsid() to + detach from any terminal and create an + independent session. In the child, call - fork() again, to ensure the daemon can - never re-aquire a terminal - again. + fork() again, to + ensure the daemon can never re-aquire + a terminal again. - Call exit() in the + Call exit() in the first child, so that only the second child (the actual daemon process) stays around. This ensures that the @@ -122,7 +130,7 @@ In the daemon process, reset the umask to 0, so that the file - modes passed to open(), mkdir() and + modes passed to open(), mkdir() and suchlike directly control the access mode of the created files and directories. @@ -134,6 +142,23 @@ blocks mount points from being unmounted. + In the daemon process, + write the daemon PID (as returned by + getpid()) to a + PID file, for example + /var/run/foobar.pid + (for a hypothetical daemon "foobar"), + to ensure that the daemon cannot be + started more than once. This must be + implemented in race-free fashion so + that the PID file is only updated when + at the same time it is verified that + the PID previously stored in the PID + file no longer exists or belongs to a + foreign process. Commonly some kind of + file locking is employed to implement + this logic. + In the daemon process, drop privileges, if possible and applicable. @@ -144,21 +169,25 @@ complete. This can be implemented via an unnamed pipe or similar communication channel that is created - before the first fork() and available - in both processes. + before the first + fork() and hence + available in both the original and the + daemon process. - Call exit() in the + Call + exit() in the original process. The process that invoked the daemon must be able to - rely that this exit() happens after - initialization is complete and all - external communication channels + rely that this + exit() happens + after initialization is complete and + all external communication channels established and accessible. - The BSD daemon() function should not be - used, as it does only a subset of these steps. + The BSD daemon() function should not be + used, as it implements only a subset of these steps. A daemon that needs to provide compatibility with SysV systems should @@ -190,6 +219,17 @@ execute them when run as new-style service. + Note that new-style init systems + guarantee execution of daemon processes in + clean process contexts: 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, and + STDIN/STDOUT/STDERR connected to + /dev/null unless + otherwise configured. The umask is reset. + It is recommended for new-style daemons to implement the following: @@ -207,9 +247,10 @@ this is used by the init system to detect service errors and problems. It is recommended to follow the exit code - scheme as defined in LSB - recommendations for SysV init scripts - (http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html). + scheme as defined in the LSB + recommendations for SysV init + scripts. As much as possible, rely on systemd's functionality to @@ -220,7 +261,10 @@ implementing your own, rely on systemd's privilege dropping code instead of implementing it in the - daemon, and similar. + daemon, and similar. See + systemd.exec5 + for the available + controls. If possible and applicable expose the daemon's control @@ -239,8 +283,8 @@ boot-up speed; your daemon can be restarted on failure, without losing any bus requests, as the bus queues - requests for activatable - services. + requests for activatable services. See + below for details. If your daemon provides services to other local @@ -255,20 +299,21 @@ protocols (such as syslog, DNS) a daemon implementing socket-based activation can be restarted without - losing a single - request. + losing a single request. See below for + details. If applicable a daemon should notify the init system about - startup completion or status - updates via the sd_notify() + startup completion or status updates + via the + sd_notify3 interface. Instead of using the - syslog() call to log directly to the + syslog() call to log directly to the system logger, a new-style daemon may choose to simply log to STDERR via - fprintf(), which is then forwarded to + fprintf(), which is then forwarded to syslog by the init system. If log priorities are necessary these can be encoded by prefixing individual log @@ -276,30 +321,259 @@ (for log priority 4 "WARNING" in the syslog priority scheme), following a similar style as the Linux kernel's - printk() priority system. In fact, using - this style of logging also enables the - init system to optionally direct all - application logging to the kernel log - buffer (kmsg), as accessible via - dmesg. + printk() priority system. In fact, + using this style of logging also + enables the init system to optionally + direct all application logging to the + kernel log buffer (kmsg), as + accessible via + dmesg1. This + kind of logging may be enabled by + setting + StandardError=syslog + in the service unit file. For details + see + sd-daemon7 + and + systemd.exec5. + + These recommendations are similar but + not identical to the Apple + MacOS X Daemon Requirements. - Bus Activation + Socket-Based Activation - Socket Activation + Bus-Based Activation - Writing Service Files + Path-Based Activation + + + + Writing Systemd Unit Files + + When writing systemd unit files, it is + recommended to consider the following + suggestions: + + + If possible do not use + the Type=forking + setting in service files. But if you + do, make sure to set the PID file path + using PIDFile=. See + systemd.service5 + for details. + + If your daemon + registers a D-Bus name on the bus, + make sure to use + Type=dbus if + possible. + + Make sure to set a + good human-readable description string + with + Description=. + + Do not disable + DefaultDependencies=, + unless you really know what you do and + your unit is involved in early boot or + late system shutdown. + + Normally, little if + any dependencies should need to + be defined explicitly. However, if you + do configure explicit dependencies, only refer to + unit names listed on + systemd.special7 + or names introduced by your own + package to keep the unit file + operating + system-independent. + + Make sure to include + an [Install] section including + installation information for the unit + file. See + systemd.unit5 + for details. To activate your service + on boot make sure to add a + WantedBy=multi-user.target + or + WantedBy=graphical.target directive. + + Installing Service Files + + 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=systemdsystemnunitdir + (for system services), + resp. pkg-config systemd + --variable=systemdsessionunitdir + (for session 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 + systemd-install1 + tool, to activate them automatically on + boot. + + Packages using + autoconf1 + 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=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)]) +AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir]) +AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir"]) + + 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 + session unit directory is left as excercise to the + reader.) + + Additionally, to ensure that + make distcheck continues to + work, it is recommended to add the following + to the top-level Makefile.am + file in + automake1-based + projects: + + DISTCHECK_CONFIGURE_FLAGS = \ + --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir) + + 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 + + In the + rpm8 + .spec file use a snippet like + the following to enable/disable the service + during installation/deinstallation. Consult + the packaging guidelines of your distribution + for details and the equivalent for other + packaging managers: + + %post +/usr/bin/systemd-install enable foobar.service foobar.socket >/dev/null 2>&1 || : + +%preun +if [ "$1" -eq 0 ]; then + /usr/bin/systemd-install disable foobar.service foobar.socket >/dev/null 2>&1 || : +fi + + + + + Porting Existing Daemons + + 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 this offers additional + functionality to the daemons as well as it + simplifies integration into new-style init + systems. + + To port an existing SysV compatible + daemon the following steps are + recommended: + + + If not already + implemented, add an optional command + line switch to the daemon to disable + daemonization. This is useful not only + for using the daemon in new-style init + systems, but also to ease debugging. + + If the daemon offers + interfaces to other software running + on the local system via local AF_UNIX + sockets, consider implementing + socket-based activation (see + above). Usually a minimal patch is + sufficient to implement this: Extend + the socket creation in the daemon code + so that + sd_listen_fds3 + is checked for already passed sockets + first. If sockets are passed + (i.e. when + sd_listen_fds() + returns a positive value), skip the + socket createn step and use the passed + sockets. Secondly, ensure that the + file-system socket nodes for local + AF_UNIX sockets used in the + socket-based activation are not + removed when the daemon shuts down, if + sockets have been passed. Third, if + the daemon normally closes all + remaining open file descriptors as + part of its initialization, the + sockets passed from the init system + must be spared. Since new-style init + systems guarantee that no left-over + file descriptors are passed to + executed processes, it might be a good + choice to simply skip the closing of + all remaining open file descriptors if + file descriptors are + passed. + + Write and install a + systemd unit file for the service (and + the sockets if socket-based activation + is used, as well as a path unit file, + if the daemon processes a spool + directory), see above for + details. + + If the daemon exposes + interfaces via D-Bus, write and + install a D-Bus activation file for + the service, see above for + details. + + @@ -309,8 +583,11 @@ See Also systemd1, - daemon3, - sd_listen_fds3 + systemd-install1, + sd-daemon7, + sd_listen_fds3, + sd_notify3, + daemon3