| <?xml version='1.0'?> <!--*-nxml-*--> |
| <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" |
| "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> |
| |
| <!-- |
| This file is part of systemd. |
| |
| Copyright 2010 Lennart Poettering |
| |
| systemd is free software; you can redistribute it and/or modify it |
| under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2 of the License, or |
| (at your option) any later version. |
| |
| systemd is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with systemd; If not, see <http://www.gnu.org/licenses/>. |
| --> |
| |
| <refentry id="daemon"> |
| |
| <refentryinfo> |
| <title>daemon</title> |
| <productname>systemd</productname> |
| |
| <authorgroup> |
| <author> |
| <contrib>Developer</contrib> |
| <firstname>Lennart</firstname> |
| <surname>Poettering</surname> |
| <email>lennart@poettering.net</email> |
| </author> |
| </authorgroup> |
| </refentryinfo> |
| |
| <refmeta> |
| <refentrytitle>daemon</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </refmeta> |
| |
| <refnamediv> |
| <refname>daemon</refname> |
| <refpurpose>Writing and Packaging System Daemons</refpurpose> |
| </refnamediv> |
| |
| <refsect1> |
| <title>Description</title> |
| |
| <para>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 |
| <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>. This |
| manual page covers both schemes, and in |
| particular includes recommendations for daemons that |
| shall be included in the systemd init system.</para> |
| |
| <refsect2> |
| <title>SysV Daemons</title> |
| |
| <para>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.</para> |
| |
| <orderedlist> |
| <listitem><para>Close all open file |
| descriptors except STDIN, STDOUT, |
| STDERR (i.e. the first three file |
| descriptors 0, 1, 2). This ensures |
| that no accidentally passed file |
| descriptor stays around in the daemon |
| process. On Linux this is best |
| implemented by iterating through |
| <filename>/proc/self/fd</filename>, |
| with a fallback of iterating from file |
| descriptor 3 to the value returned by |
| <function>getrlimit()</function> for |
| RLIMIT_NOFILE.</para></listitem> |
| |
| <listitem><para>Reset all signal |
| handlers to their default. This is |
| best done by iterating through the |
| available signals up to the limit of |
| _NSIG and resetting them to |
| SIG_DFL.</para></listitem> |
| |
| <listitem><para>Reset the signal mask |
| using |
| <function>sigprocmask()</function>.</para></listitem> |
| |
| <listitem><para>Sanitize the |
| environment block, removing or |
| resetting environment variables that |
| might negatively impact daemon |
| runtime.</para></listitem> |
| |
| <listitem><para>Call <function>fork()</function>, |
| to create a background |
| process.</para></listitem> |
| |
| <listitem><para>In the child, call |
| <function>setsid()</function> to |
| detach from any terminal and create an |
| independent session.</para></listitem> |
| |
| <listitem><para>In the child, call |
| <function>fork()</function> again, to |
| ensure the daemon can never re-aquire |
| a terminal again.</para></listitem> |
| |
| <listitem><para>Call <function>exit()</function> in the |
| first child, so that only the second |
| child (the actual daemon process) |
| stays around. This ensures that the |
| daemon process is reparented to |
| init/PID 1, as all daemons should |
| be.</para></listitem> |
| |
| <listitem><para>In the daemon process, |
| connect <filename>/dev/null</filename> |
| to STDIN, STDOUT, |
| STDERR.</para></listitem> |
| |
| <listitem><para>In the daemon process, |
| reset the umask to 0, so that the file |
| modes passed to <function>open()</function>, <function>mkdir()</function> and |
| suchlike directly control the access |
| mode of the created files and |
| directories.</para></listitem> |
| |
| <listitem><para>In the daemon process, |
| change the current directory to the |
| root directory (/), in order to avoid |
| that the daemon involuntarily |
| blocks mount points from being |
| unmounted.</para></listitem> |
| |
| <listitem><para>In the daemon process, |
| write the daemon PID (as returned by |
| <function>getpid()</function>) to a |
| PID file, for example |
| <filename>/var/run/foobar.pid</filename> |
| (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.</para></listitem> |
| |
| <listitem><para>In the daemon process, |
| drop privileges, if possible and |
| applicable.</para></listitem> |
| |
| <listitem><para>From the daemon |
| process notify the original process |
| started that initialization is |
| complete. This can be implemented via |
| an unnamed pipe or similar |
| communication channel that is created |
| before the first |
| <function>fork()</function> and hence |
| available in both the original and the |
| daemon process.</para></listitem> |
| |
| <listitem><para>Call |
| <function>exit()</function> in the |
| original process. The process that |
| invoked the daemon must be able to |
| rely that this |
| <function>exit()</function> happens |
| after initialization is complete and |
| all external communication channels |
| established and |
| accessible.</para></listitem> |
| </orderedlist> |
| |
| <para>The BSD <function>daemon()</function> function should not be |
| used, as it implements only a subset of these steps.</para> |
| |
| <para>A daemon that needs to provide |
| compatibility with SysV systems should |
| implement the scheme pointed out |
| above. However, it is recommended to make this |
| behaviour optional and configurable via a |
| command line argument, to ease debugging as |
| well as to simplify integration into systems |
| using systemd.</para> |
| </refsect2> |
| |
| <refsect2> |
| <title>New-Style Daemons</title> |
| |
| <para>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.</para> |
| |
| <para>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 init system it is recommended not to |
| execute them when run as new-style |
| service.</para> |
| |
| <para>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 |
| <filename>/dev/null</filename> unless |
| otherwise configured. The umask is reset.</para> |
| |
| <para>It is recommended for new-style daemons |
| to implement the following:</para> |
| |
| <orderedlist> |
| <listitem><para>If SIGTERM is |
| received, shut down the daemon and |
| exit cleanly.</para></listitem> |
| |
| <listitem><para>If SIGHUP is received, |
| reload the configuration files, if |
| this applies.</para></listitem> |
| |
| <listitem><para>Provide a correct exit |
| code from the main daemon process, as |
| 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 the <ulink |
| url="http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html">LSB |
| recommendations for SysV init |
| scripts</ulink>.</para></listitem> |
| |
| <listitem><para>If possible and |
| applicable expose the daemon's control |
| interface via the D-Bus IPC system and |
| grab a bus name as last step of |
| initialization.</para></listitem> |
| |
| <listitem><para>For integration in |
| systemd, provide a |
| <filename>.service</filename> unit |
| file that carries information about |
| starting, stopping and otherwise |
| maintaining the daemon. See |
| <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry> |
| for details.</para></listitem> |
| |
| <listitem><para>As much as possible, |
| rely on the init systemd's |
| functionality to limit the access of |
| the daemon to files, services and |
| other resources. i.e. in the case of |
| systemd, rely on systemd's resource |
| limit control instead of implementing |
| your own, rely on systemd's privilege |
| dropping code instead of implementing |
| it in the daemon, and similar. See |
| <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> |
| for the available |
| controls.</para></listitem> |
| |
| <listitem><para>If D-Bus is used, make |
| your daemon bus-activatable, via |
| supplying a D-Bus service activation |
| configuration file. This has multiple |
| advantages: your daemon may be started |
| lazily on-demand; it may be started in |
| parallel to other daemons requiring it |
| -- which maximizes parallelization and |
| boot-up speed; your daemon can be |
| restarted on failure, without losing |
| any bus requests, as the bus queues |
| requests for activatable services. See |
| below for details.</para></listitem> |
| |
| <listitem><para>If your daemon |
| provides services to other local |
| processes or remote clients via a |
| socket, it should be made |
| socket-activatable following the |
| scheme pointed out below. Like D-Bus |
| activation this enables on-demand |
| starting of services as well as it |
| allows improved parallelization of |
| service start-up. Also, for state-less |
| protocols (such as syslog, DNS) a |
| daemon implementing socket-based |
| activation can be restarted without |
| losing a single request. See below for |
| details.</para></listitem> |
| |
| <listitem><para>If applicable a daemon |
| should notify the init system about |
| startup completion or status updates |
| via the |
| <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry> |
| interface.</para></listitem> |
| |
| <listitem><para>Instead of using the |
| <function>syslog()</function> call to log directly to the |
| system logger, a new-style daemon may |
| choose to simply log to STDERR via |
| <function>fprintf()</function>, which is then forwarded to |
| syslog by the init system. If log |
| priorities are necessary these can be |
| encoded by prefixing individual log |
| lines with strings like "<4>" |
| (for log priority 4 "WARNING" in the |
| syslog priority scheme), following a |
| similar style as the Linux kernel's |
| <function>printk()</function> 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 |
| <citerefentry><refentrytitle>dmesg</refentrytitle><manvolnum>1</manvolnum></citerefentry>. This |
| kind of logging may be enabled by |
| setting |
| <varname>StandardError=syslog</varname> |
| in the service unit file. For details |
| see |
| <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry> |
| and |
| <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem> |
| |
| </orderedlist> |
| |
| <para>These recommendations are similar but |
| not identical to the <ulink |
| url="http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/LaunchOnDemandDaemons.html#//apple_ref/doc/uid/TP40001762-104738">Apple |
| MacOS X Daemon Requirements</ulink>.</para> |
| </refsect2> |
| |
| </refsect1> |
| <refsect1> |
| <title>Activation</title> |
| |
| <para>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: |
| <filename>bluetoothd.service</filename> 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.</para> |
| |
| <refsect2> |
| <title>Activation on Boot</title> |
| |
| <para>Old-style daemons are usually activated |
| exclusively on boot (and manually by the |
| administrator) via SysV init scripts, as |
| detailed in the <ulink |
| url="http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html">LSB |
| Linux Standard Base Core |
| Specification</ulink>. This method of |
| activation is supported ubiquitiously on Linux |
| init systems, both old-style and new-style |
| systems. Among other issues SysV init scripts |
| have the disadvantage of involving shell |
| scripts in the boot process. New-style init |
| systems generally employ updated versions of |
| activation, both during boot-up and during |
| runtime and using more minimal service |
| description files.</para> |
| |
| <para>In systemd, if the developer or |
| administrator wants to make sure a service or |
| other unit is activated automatically on boot |
| it is recommended to place a symlink to the |
| unit file in the <filename>.wants/</filename> |
| directory of either |
| <filename>multi-user.target</filename> or |
| <filename>graphical.target</filename>, which |
| are normally used as boot targets at system |
| startup. See |
| <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> |
| for details about the |
| <filename>.wants/</filename> directories, and |
| <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry> |
| for details about the two boot targets.</para> |
| |
| </refsect2> |
| |
| <refsect2> |
| <title>Socket-Based Activation</title> |
| |
| <para>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 employ |
| 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 init system. Based on |
| per-daemon configuration the init system |
| 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.</para> |
| |
| <para>New-style daemons which support socket |
| activation must be able to receive their |
| sockets from the init system, instead of of |
| creating and binding them themselves. For |
| details about the programming interfaces for |
| this scheme provided by systemd see |
| <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry> |
| and |
| <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>. 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.</para> |
| |
| <para>systemd implements socket-based |
| activation via <filename>.socket</filename> |
| units, which are described in |
| <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>. When |
| configuring socket units for socket-based |
| activation it is essential that all listening |
| sockets are pulled in by the special target |
| unit <filename>sockets.target</filename>. It |
| is recommended to place a |
| <varname>WantedBy=sockets.target</varname> |
| directive in the <literal>[Install]</literal> |
| section, to automatically add such a |
| dependency on installation of a socket |
| unit. Unless |
| <varname>DefaultDependencies=no</varname> is |
| set the necessary ordering dependencies are |
| implicitly created for all socket units. For |
| more information about |
| <filename>sockets.target</filename> see |
| <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>. It |
| is not necessary or recommended to place any |
| additional dependencies on socket units (for |
| example from |
| <filename>multi-user.target</filename> or |
| suchlike) when one is installed in |
| <filename>sockets.target</filename>.</para> |
| </refsect2> |
| |
| <refsect2> |
| <title>Bus-Based Activation</title> |
| |
| <para>When the D-Bus IPC system is used for |
| communication with clients, new-style daemons |
| should employ 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 |
| <varname>SystemdService=</varname> 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 |
| <filename>org.freedesktop.RealtimeKit.service</filename>, |
| make sure to set |
| <varname>SystemdService=rtkit-daemon.service</varname> |
| in that file, to bind it to the systemd |
| service |
| <filename>rtkit-daemon.service</filename>. This |
| is needed to make sure that the daemon is |
| started in a race-free fashion when activated |
| via multiple mechanisms simultaneously.</para> |
| </refsect2> |
| |
| <refsect2> |
| <title>Device-Based Activation</title> |
| |
| <para>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 |
| "<literal>systemd</literal>". 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 |
| <varname>SYSTEMD_WANTS=</varname> |
| property. See |
| <citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry> |
| for details. Often it is nicer to pull in |
| services from devices only indirectly via |
| dedicated targets. Example: instead of pulling |
| in <filename>bluetoothd.service</filename> |
| from all the various bluetooth dongles and |
| other hardware available, pull in |
| bluetooth.target from them and |
| <filename>bluetoothd.service</filename> from |
| that target. This provides for nicer |
| abstraction and gives administrators the |
| option to enable |
| <filename>bluetoothd.service</filename> via |
| controlling a |
| <filename>bluetooth.target.wants/</filename> |
| symlink uniformly with a command like |
| <command>enable</command> of |
| <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> |
| instead of manipulating the udev |
| ruleset.</para> |
| </refsect2> |
| |
| <refsect2> |
| <title>Path-Based Activation</title> |
| |
| <para>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 |
| <filename>.path</filename> units, as outlined |
| in |
| <citerefentry><refentrytitle>systemd.path</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para> |
| </refsect2> |
| |
| <refsect2> |
| <title>Timer-Based Activation</title> |
| |
| <para>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 <filename>.timer</filename> units, as |
| described in |
| <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para> |
| </refsect2> |
| |
| <refsect2> |
| <title>Other Forms of Activation</title> |
| |
| <para>Other forms of activation have been |
| suggested and implemented in some |
| systems. However, often there are 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 <filename>.socket</filename> |
| 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 |
| socket option, as accessible via |
| <varname>FreeBind=yes</varname> in systemd |
| socket files (see |
| <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry> |
| 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 IO 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 IO schedulers. If a process |
| executed by the init system shall not |
| negatively impact the amount of CPU or IO |
| bandwith available to other processes, it |
| should be configured with |
| <varname>CPUSchedulingPolicy=idle</varname> |
| and/or |
| <varname>IOSchedulingClass=idle</varname>. 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.</para> |
| </refsect2> |
| |
| </refsect1> |
| <refsect1> |
| <title>Integration with Systemd</title> |
| |
| <refsect2> |
| <title>Writing Systemd Unit Files</title> |
| |
| <para>When writing systemd unit files, it is |
| recommended to consider the following |
| suggestions:</para> |
| |
| <orderedlist> |
| <listitem><para>If possible do not use |
| the <varname>Type=forking</varname> |
| setting in service files. But if you |
| do, make sure to set the PID file path |
| using <varname>PIDFile=</varname>. See |
| <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry> |
| for details.</para></listitem> |
| |
| <listitem><para>If your daemon |
| registers a D-Bus name on the bus, |
| make sure to use |
| <varname>Type=dbus</varname> in the |
| service file if |
| possible.</para></listitem> |
| |
| <listitem><para>Make sure to set a |
| good human-readable description string |
| with |
| <varname>Description=</varname>.</para></listitem> |
| |
| <listitem><para>Do not disable |
| <varname>DefaultDependencies=</varname>, |
| unless you really know what you do and |
| your unit is involved in early boot or |
| late system shutdown.</para></listitem> |
| |
| <listitem><para>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 |
| <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry> |
| or names introduced by your own |
| package to keep the unit file |
| operating |
| system-independent.</para></listitem> |
| |
| <listitem><para>Since not all syslog |
| implementations are socket-activatable |
| yet, it is recommended to place an |
| <varname>After=syslog.target</varname> |
| dependency in service files for |
| daemons that can log to |
| syslog. <filename>syslog.target</filename> |
| then either pulls in the syslog daemon |
| itself or simply the activation |
| socket. A <varname>Wants=</varname> or |
| even <varname>Requires=</varname> |
| dependency should generally not be |
| added, since it should be up to the |
| administrator whether he wants to |
| enable logging or not, and most syslog |
| clients work fine if no log daemon is |
| running.</para></listitem> |
| |
| <listitem><para>Make sure to include |
| an <literal>[Install]</literal> |
| section including installation |
| information for the unit file. See |
| <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> |
| for details. To activate your service |
| on boot make sure to add a |
| <varname>WantedBy=multi-user.target</varname> |
| or |
| <varname>WantedBy=graphical.target</varname> |
| directive. To activate your socket on |
| boot, make sure to add |
| <varname>WantedBy=sockets.target</varname>. Usually |
| you also want to make sure that when |
| your service is installed your socket |
| is installed too, hence add |
| <varname>Also=foo.socket</varname> in |
| your service file |
| <filename>foo.service</filename>, for |
| a hypothetical program |
| <filename>foo</filename>.</para></listitem> |
| |
| </orderedlist> |
| </refsect2> |
| |
| <refsect2> |
| <title>Installing Systemd Service Files</title> |
| |
| <para>At the build installation time |
| (e.g. <command>make install</command> during |
| package build) packages are recommended to |
| install their systemd unit files in the |
| directory returned by <command>pkg-config |
| systemd |
| --variable=systemdsystemunitdir</command> (for |
| system services), resp. <command>pkg-config |
| systemd |
| --variable=systemdsessionunitdir</command> |
| (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. <command>rpm -i</command> |
| by the administrator) symlinks should be |
| created in the systemd configuration |
| directories via the <command>enable</command> |
| command of the |
| <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> |
| tool, to activate them automatically on |
| boot.</para> |
| |
| <para>Packages using |
| <citerefentry><refentrytitle>autoconf</refentrytitle><manvolnum>1</manvolnum></citerefentry> |
| are recommended to use a configure script |
| excerpt like the following to determine the |
| unit installation path during source |
| configuration:</para> |
| |
| <programlisting>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"])</programlisting> |
| |
| <para>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.)</para> |
| |
| <para>Additionally, to ensure that |
| <command>make distcheck</command> continues to |
| work, it is recommended to add the following |
| to the top-level <filename>Makefile.am</filename> |
| file in |
| <citerefentry><refentrytitle>automake</refentrytitle><manvolnum>1</manvolnum></citerefentry>-based |
| projects:</para> |
| |
| <programlisting>DISTCHECK_CONFIGURE_FLAGS = \ |
| --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)</programlisting> |
| |
| <para>Finally, unit files should be installed in the system with an automake excerpt like the following:</para> |
| |
| <programlisting>if HAVE_SYSTEMD |
| systemdsystemunit_DATA = \ |
| foobar.socket \ |
| foobar.service |
| endif</programlisting> |
| |
| <para>In the |
| <citerefentry><refentrytitle>rpm</refentrytitle><manvolnum>8</manvolnum></citerefentry> |
| <filename>.spec</filename> 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 |
| package managers:</para> |
| |
| <programlisting>%post |
| if [ $1 -eq 1 ]; then |
| # Enable (but don't start) the units by default |
| /bin/systemctl enable foobar.service foobar.socket >/dev/null 2>&1 || : |
| |
| # Alternatively, just call /bin/systemctl daemon-reload here, |
| # if the daemon should not be enabled by default on package |
| # installation |
| fi |
| |
| %preun |
| if [ $1 -eq 0 ]; then |
| # Disable and stop the units |
| /bin/systemctl disable foobar.service foobar.socket >/dev/null 2>&1 || : |
| /bin/systemctl stop foobar.service foobar.socket >/dev/null 2>&1 || : |
| fi |
| |
| %postun |
| if [ $1 -ge 1 ] ; then |
| # On upgrade, reload init system configuration if we changed unit files |
| /bin/systemctl daemon-reload >/dev/null 2>&1 || : |
| # On upgrade, restart the daemon |
| /bin/systemctl try-restart foobar.service >/dev/null 2>&1 || : |
| fi</programlisting> |
| |
| <para>Depending on whether your service should |
| or should not be started/stopped/restarted |
| during package installation, deinstallation or |
| upgrade, a different set of commands may be |
| specified. See |
| <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> |
| for details.</para> |
| |
| <para>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:</para> |
| |
| <programlisting>%triggerin -- foobar < 0.47.11-1 |
| if /sbin/chkconfig foobar ; then |
| /bin/systemctl enable foobar.service foobar.socket >/dev/null 2>&1 || : |
| fi</programlisting> |
| |
| <para>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 |
| <command>chkconfig</command> 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.</para> |
| </refsect2> |
| </refsect1> |
| |
| <refsect1> |
| <title>Porting Existing Daemons</title> |
| |
| <para>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.</para> |
| |
| <para>To port an existing SysV compatible daemon the |
| following steps are recommended:</para> |
| |
| <orderedlist> |
| <listitem><para>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.</para></listitem> |
| |
| <listitem><para>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 |
| <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry> |
| is checked for already passed sockets |
| first. If sockets are passed (i.e. when |
| <function>sd_listen_fds()</function> returns a |
| positive value), skip the socket creation 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 sockets are |
| passed.</para></listitem> |
| |
| <listitem><para>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.</para></listitem> |
| |
| <listitem><para>If the daemon exposes |
| interfaces via D-Bus, write and install a |
| D-Bus activation file for the service, see |
| above for details.</para></listitem> |
| </orderedlist> |
| </refsect1> |
| |
| <refsect1> |
| <title>See Also</title> |
| <para> |
| <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, |
| <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>, |
| <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>, |
| <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>, |
| <citerefentry><refentrytitle>daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>, |
| <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry> |
| </para> |
| </refsect1> |
| |
| </refentry> |