Путеводитель по Руководству Linux

  User  |  Syst  |  Libr  |  Device  |  Files  |  Other  |  Admin  |  Head  |



   daemon    ( 7 )

написание и упаковка системных демонов (Writing and packaging system daemons)

  Name  |  Description  |  Activation  |    Integration with systemd    |  Porting existing daemons  |  Placing daemon data  |  See also  |  Note  |

INTEGRATION WITH SYSTEMD

Writing systemd Unit Files When writing systemd unit files, it is recommended to consider the following suggestions:

1. 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.service(5) for details.

2. If your daemon registers a D-Bus name on the bus, make sure to use Type=dbus in the service file if possible.

3. Make sure to set a good human-readable description string with Description=.

4. Do not disable DefaultDependencies=, unless you really know what you do and your unit is involved in early boot or late system shutdown.

5. 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.special(7) or names introduced by your own package to keep the unit file operating system-independent.

6. Make sure to include an [Install] section including installation information for the unit file. See systemd.unit(5) for details. To activate your service on boot, make sure to add a WantedBy=multi-user.target or WantedBy=graphical.target directive. To activate your socket on boot, make sure to add WantedBy=sockets.target. Usually, you also want to make sure that when your service is installed, your socket is installed too, hence add Also=foo.socket in your service file foo.service, for a hypothetical program foo.

Installing systemd 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=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.

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"])

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.)

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)

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 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.

At the top of the file:

BuildRequires: systemd %{?systemd_requires}

And as scriptlets, further down:

%post %systemd_post foobar.service foobar.socket

%preun %systemd_preun foobar.service foobar.socket

%postun %systemd_postun

If the service shall be restarted during upgrades, replace the "%postun" scriptlet above with the following:

%postun %systemd_postun_with_restart foobar.service

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.

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

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.