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
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
-->
<refnamediv>
<refname>daemon</refname>
- <refpurpose>Writing and Packaging System Daemons</refpurpose>
+ <refpurpose>Writing and packaging system daemons</refpurpose>
</refnamediv>
<refsect1>
<listitem><para>In the child, call
<function>fork()</function> again, to
- ensure the daemon can never re-aquire
+ ensure the daemon can never re-acquire
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
+ daemon process is re-parented to
init/PID 1, as all daemons should
be.</para></listitem>
<function>exit()</function> in the
original process. The process that
invoked the daemon must be able to
- rely that this
+ rely on that this
<function>exit()</function> happens
after initialization is complete and
all external communication channels
- established and
+ are established and
accessible.</para></listitem>
</orderedlist>
compatibility with SysV systems should
implement the scheme pointed out
above. However, it is recommended to make this
- behaviour optional and configurable via a
+ behavior optional and configurable via a
command line argument, to ease debugging as
well as to simplify integration into systems
using systemd.</para>
for details.</para></listitem>
<listitem><para>As much as possible,
- rely on the init systemd's
+ rely on the init system's
functionality to limit the access of
the daemon to files, services and
other resources. i.e. in the case of
<listitem><para>Instead of using the
<function>syslog()</function> call to log directly to the
- system logger, a new-style daemon may
+ system syslog service, 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
<varname>StandardError=syslog</varname>
in the service unit file. For details
see
- <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
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
+ activation is supported ubiquitously on Linux
init systems, both old-style and new-style
systems. Among other issues SysV init scripts
have the disadvantage of involving shell
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 als all sockets
+ 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
<para>New-style daemons which support socket
activation must be able to receive their
- sockets from the init system, instead of of
+ sockets from the init system, instead 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
+ <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>. For
details about porting existing daemons to
socket-based activation see below. With
minimal effort it is possible to implement
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
+ <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
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
+ bandwidth available to other processes, it
should be configured with
<varname>CPUSchedulingPolicy=idle</varname>
and/or
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
directory returned by <command>pkg-config
systemd
--variable=systemdsystemunitdir</command> (for
- system services), resp. <command>pkg-config
+ system services) or <command>pkg-config
systemd
- --variable=systemdsessionunitdir</command>
- (for session services). This will make the
+ --variable=systemduserunitdir</command>
+ (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
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>
+if test "x$with_systemdsystemunitdir" != xno; then
+ AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
+fi
+AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])</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
+ user unit directory is left as an exercise for the
reader.)</para>
<para>Additionally, to ensure that
<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
+ <filename>.spec</filename> 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:</para>
+ 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 || :
+ <para>At the top of the file:</para>
- # Alternatively, just call /bin/systemctl daemon-reload here,
- # if the daemon should not be enabled by default on package
- # installation
-fi
+ <programlisting>BuildRequires: systemd
+%{?systemd_requires}</programlisting>
+
+ <para>And as scriptlets, further down:</para>
+
+ <programlisting>%post
+%systemd_post foobar.service foobar.socket
%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
+%systemd_preun foobar.service foobar.socket
%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>
+%systemd_postun</programlisting>
+
+ <para>If the service shall be restarted during
+ upgrades replace the
+ <literal>%postun</literal> scriptlet above
+ with the following:</para>
+
+ <programlisting>%postun
+%systemd_postun_with_restart foobar.service</programlisting>
+
+ <para>Note that
+ <literal>%systemd_post</literal> and
+ <literal>%systemd_preun</literal> expect the
+ names of all units that are installed/removed
+ as arguments, separated by
+ spaces. <literal>%systemd_postun</literal>
+ expects no
+ arguments. <literal>%systemd_postun_with_restart</literal>
+ expects the units to restart as
+ arguments.</para>
<para>To facilitate upgrades from a package
version that shipped only SysV init scripts to
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 || :
+ <programlisting>%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</programlisting>
<para>Where 0.47.11-1 is the first package
<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
+ 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
<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-daemon</refentrytitle><manvolnum>3</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>,