Packaging:Systemd

= Fedora systemd Services = This document describes the guidelines for systemd services, for use and inclusion in Fedora packages.

Definitions
Since systemd includes some concepts which are extensions of previous concepts, the following definitions may be useful:

Service: A process or task executed and controlled by the init system (e.g. systemd). Traditional Service: A service which is explicitly started or stopped, either by the init system at boot or manually by a superuser. In systemd, one of several types of service controlled by a  file. Activated service: A service that is not (or not necessarily) started explicitly by the user but start when certain other events happen or certain state becomes true. Socket-activated Service: A service which is waiting for traffic across a socket before activating. In systemd, controlled by a  file. D-Bus service: A service which activates in response to a message from the D-Bus system bus. Unit file: The systemd equivalent of a SysV initscript.

Unit Files
Each package that contains software that wants/needs to start a traditional service at boot MUST have a systemd unit file.

Ideally, systemd unit files are reusable across distributions and shipped with the upstream packages. Please consider working with upstream to integrate the systemd files you prepare in the upstream sources. Information for developers on how to integrate systemd support best with their build system you may find on http://0pointer.de/public/systemd-man/daemon.html

Naming
Unit files for traditional services have a naming scheme of foobar.service. When considering what basename to use, keep in mind that we'd like to use the same service names for software across distributions. We'd also like to ship the  files in the upstream packages. These desires create a few guides for naming a unit file:


 * Follow upstream if they're already distributing a  file and it's not likely to conflict with other packages.
 * Look at packages in other distros or talk with the maintainers of those packages and upstream to try to come up with a common name.
 * Unit files should be named after the software implementation that they support as opposed to the generic type of software. So, a good name would be  and bad names would be   or   as there are multiple httpd implementations and multiple projects produced by the apache foundation.

For backwards compatibility you may also want to create a symlink from an older, name to the new name. In the above example, for instance, Fedora has always used  for the service. When creating the new  file, also create a symlink named   that points at. Then end users that are used to using  will have it continue to work.

[Unit]
Every  file must begin with a   section:

[Unit] Description=A brief human readable string describing the service (not the  file!) After=syslog.target

The  line must not exceed 80 characters, and must describe the service, and not the   file. For example, "Apache Web Server" is a good description, but "Starts and Stops the Apache Web Server" is a bad one.

specifies that this service may only start after the listed services have started. In this example, the service starts after syslog since syslog can be used for logging. (Most daemon programs can use syslog for logging so when in doubt, it's good to include this.)

[Service]
Next, the  file must have a   section:

[Service] Type=... ExecStart=... ExecReload=...

The  setting is very important. For D-Bus services this should be "dbus", for traditional services "forking" is usually a good idea, for services not offering any interfaces to other services "simple" is best. For "one-shot" scripts "oneshot" is ideal, often combined with . See http://0pointer.de/public/systemd-man/systemd.service.html for further discussion on the topic. Since "simple" is the default type, files which would normally set  may simply omit the  line altogether.

should be set for all services connecting to D-Bus. (i.e. it is a must for those where, but might make sense otherwise, too) Omit this option if your service does not take a name on the bus.

is necessary for all services. This line defines the string that you would run to start the daemon, along with any necessary options.

should be specified for all services supporting reload. It is highly recommended to add code here that synchronously reloads the configuration file here (i.e.  is usually a poor choice, due to its asynchronous nature). Omit this option if your service does not support reloading.

[Install]
Finally, the  file should have an   section:

[Install] WantedBy=...

The recommended parameters for  are either   (services related to the graphical user interface) or   (for everything else). When the user (or our scriptlets) invoke  the service will be set to start in these targets.

For more information regarding these options see http://0pointer.de/public/systemd-man/systemd.unit.html and http://0pointer.de/public/systemd-man/systemd.service.html

EnvironmentFiles and support for /etc/sysconfig files
The  line in the   section of   files is used to support loading environment variables that can be used in unit files. For instance, if your sysv-initscript used a file in /etc/sysconfig to set command line options, you can use  like so:

Example: [Service] Type=forking EnvironmentFile=-/etc/sysconfig/httpd ExecStart=/usr/sbin/httpd $OPTIONS ExecReload=/usr/sbin/httpd $OPTIONS -k restart

You may then refer to variables set in the  file with and, in the lines (and related lines). ( expands the variable into one word,   splits up the variable value at whitespace into multiple words)

The "-" on the  line ensures that no error messages is generated if the environment file does not exist. Since many of these files were optional in sysvinit, you should include the "-" when using this directive.

Although environment files are easy to use, upstream systemd recommends a different approach. Their recommendation for administrators who need to reconfigure systemd  files is to copy them from   to   and modify them there. Unit files in  override those in   if they otherwise carry the same name.

Either approach is valid in Fedora.

Fields to avoid
For most services, we do not want to use requirement dependencies in the section, such as  or . Instead exclusively use ordering dependencies:   and . This is used to implement loose coupling: if someone asks two services to start at the same time, systemd will properly order their startup but not make it strictly necessary to run one if the other is started.

If you use a requirement dependency, use  rather than , to make things a little bit more robust. If you use a requirement dependency in almost all cases you should also add an ordering dependency, as ordering and requirement dependencies are orthogonal in systemd.

Here's an example of this common case:
 * 1) A web application needs postgresql to store its data.
 * 2) It is set to start   postgresql.  On startup, the web application does not start until postgresql does.
 * 3) Once running, the system administrator needs to restart postgresql due to a config tweak.
 * 4) Since only   was used, the web application may be temporarily unable to serve some requests but it does not need to restart in order to serve pages after the database comes back up.

Avoid referring to  units in all lines taking unit names (such as  ), these are legacy names existing for compatibility with SysV only.

Avoid  (in the   section). Usually it is a better idea to symlink an additional name in the file system. Note that a name listed in  is only useful when a service file is already loaded. However, systemd loads only the service files actually referred to in another loaded service, and uses the filenames during the search. Hence a name in  is not useful as a search key, but a symlink in the file system is. Also do not put a (redundant)  line into a file called. We want to keep our service files short.

Avoid using. Use  instead. (same for ). syslog is a better target, because it is where service logging should primarily go. While messages written to kmsg eventually end up in syslog too they are normally attributed to the kernel, and lose much of its meta data. is recommended for all services which generate output on stdout or stderr which shall be piped to syslog. Note that if is set   is implied unless is explicitly configured too. That basically means that you never need to use  in normal cases. Just use . A full description of these options can be found here: http://0pointer.de/public/systemd-man/systemd.exec.html

Example Unit file
This is an example systemd unit  file for ABRT:

[Unit] Description=ABRT Automated Bug Reporting Tool After=syslog.target

[Service] Type=dbus BusName=com.redhat.abrt ExecStart=/usr/sbin/abrtd -d -s

[Install] WantedBy=multi-user.target

Activation
Systemd allows for three forms of activated services:, , and.

Hardware activation
Hardware activation occurs when a service is installed but only turns on if a certain type of hardware is installed. Enabling of the service is normally done with a udev rule. At this time we do not have further guidance on how to write those udev rules. The service itself installs its  files in the normal places and are installed by the normal  systemd scriptlets. These services should never be enabled by the package as they will be enabled by udev.

Socket activation
Socket activation occurs when a service allows systemd to listen for connections to a specific socket and, when systemd receives a connection on that socket, it starts the service. To do this, the upstream source needs to have some minor coding work to let systemd listen for connections on the socket and there needs to be a  file in  that tells systemd to listen to that socket and what to start when a connection is received. This is similar in function to inetd and some, but not all, services coded to work with inetd will work with socket activation. Simila to inetd, using socket activation for on-demand loading will impose a startup time penalty so we currently do not use this feature in Fedora.

However, socket activation can also be used to allow parallel startup of services. If a service supports systemd socket activation as described above and we additionally start it explicitly on boot, then systemd will start it but allow things that depend on it to startup at the same time. If the dependent service makes a request to the socket activatable service before it has come up, then systemd will cause the request to wait until the socket activatable service has come up and can process the request. To achieve this effect, the service must be socket activatable as described above, the  file for the service needs to have a   line for the , and the service must autostart. Since Fedora currently doesn't want any services to do on-demand loading, all socket activated services must autostart.

In practical terms this means if the upstream tarball ships with a socket file you need to contact FESCo to get permission to enable your service on boot. Once you have permission, you can package the  file and use the systemd scriptlets that enable the service by default. You need to also check the  file to make sure it has a   entry on the   file as that ensures that starting the service will also inform systemd of the socket.

DBus activation
In order to allow parallel startup of a D-Bus service and its consumers it is essential that D-Bus services can be bus activated and the D-Bus activation request is forwarded from the D-Bus system bus to systemd so that you end up with only a single instance of the service, even if a service is triggered by both boot-up and activation. If historically your D-Bus service was not bus-activated but started via a SysV init script, it should be updated to use bus activation. This may be implemented by dropping a D-Bus  file in   and use the   directive therein to redirect the activation to systemd.

Here's an example for a D-Bus bus-activable service. The ConsoleKit bus activation file /usr/share/dbus-1/system-services/org.freedesktop.ConsoleKit.service:

[D-BUS Service] Name=org.freedesktop.ConsoleKit Exec=/usr/sbin/console-kit-daemon --no-daemon User=root SystemdService=console-kit-daemon.service

And the matching systemd unit file /lib/systemd/system/console-kit-daemon.service:

[Unit] Description=Console Manager After=syslog.target

[Service] Type=dbus BusName=org.freedesktop.ConsoleKit ExecStart=/usr/sbin/console-kit-daemon --no-daemon

As you can see  is used in the D-Bus activation file to bind the systemd service to the D-Bus service.

Traditionally, bus activated D-Bus services could not be disabled without uninstalling them entirely. systemd allows you to disable services by making D-Bus invoke an alias systemd service name (that can be created or removed to enable/disable activation) as an intermediary for the real service.

You can easily implement disabling by directing the D-Bus service to an alias name of the real service file (in the filesystem this shows up as a symlink placed in /etc/systemd/system to the real service file). This alias is then controlled via "systemctl enable" and "systemctl disable". It is a good idea (though technically not necessary) to name this alias name after the D-Bus bus name of the service, prefixed with "dbus-". Example for Avahi, a service that the admin might need to disable: set instead of in the D-Bus activation file, and then make an optional alias of avahi-daemon.service that can be controlled via the  directive in the   section of the systemd service file. This directive is then read by "systemctl enable" and "systemctl disable" to create resp. remove a symlink to make the service available resp. unavailable under this additional name. A full example for the Avahi case:

Here is the D-Bus .service file for Avahi (/usr/share/dbus-1/system-services/org.freedesktop.Avahi.service): [D-BUS Service] Name=org.freedesktop.Avahi SystemdService=dbus-org.freedesktop.Avahi.service

Exec=/bin/false
 * 1) This service should not be bus activated if systemd isn't running,
 * 2) so that activation won't conflict with the init script startup.

Here is the Avahi systemd unit  file (/lib/systemd/system/avahi-daemon.service):

[Unit] Description=Avahi mDNS/DNS-SD Stack Requires=avahi-daemon.socket After=syslog.target

[Service] Type=dbus BusName=org.freedesktop.Avahi ExecStart=/usr/sbin/avahi-daemon -s ExecReload=/usr/sbin/avahi-daemon -r NotifyAccess=main

[Install] WantedBy=multi-user.target Also=avahi-daemon.socket Alias=dbus-org.freedesktop.Avahi.service

The  line ensures that the existance of the /etc/systemd/system/dbus-org.freedesktop.Avahi.service symlink can be controlled by "systemctl enable" and "systemctl disable".

Note that the creation/removal of the alias symlinks should be done with "systemctl enable" and "systemctl disable" only. You should not create these symlinks manually.

In general, it is also recommended to supply native systemd units for all services that are already bus activatable, so that these services can be controlled and supervised centrally like any other service with tools such as systemctl. A similar logic like the one shown above should apply.

See the D-Bus documentation for more information about bus activation: http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-starting-services

= Packaging =

Filesystem locations
Packages with systemd unit files must put them into. evaluates to /lib/systemd/system on all Fedora systems (F-15+). Unit files are architecture independent (hence, not ) and needed early in the boot process.

Please note that in order for the  macro to exist, your package must have: BuildRequires: systemd-units

%files section
Systemd unit  files must not be marked as   files. If the user wants to reconfigure a  file he should copy the   file from /lib/systemd/system to /etc/systemd/system and edit it there. Unit files in /etc/systemd/system override those in /lib/systemd/system if they carry the same name.

Unit files in spec file scriptlets
Information on proper handling of unit files in spec file scriptlets can be found here: Packaging:ScriptletSnippets

Tmpfiles.d
tmpfiles.d is a service provided systemd in Fedora 15 and later for managing temporary files and directories for daemons. For more information on how to use Tmpfiles.d in Fedora Packages, please see: Packaging:Tmpfiles.d

Why don't we....

 * Start the service after installation?

Installations can be in changeroots, in an installer context, or in other situations where you don't want the services autostarted.