[arch-dev-public] [RFC] systemd service files policy
Tom Gundersen
teg at jklm.no
Thu Aug 23 11:32:44 EDT 2012
Hi guys,
We are hard at work adding systemd service files, and I thought it
might be worth discussing a few guidelines for how to do it (should
eventually end up in the wiki I suppose, but thought it would be best
to start the discussion here).
I propose (based on input gathered on IRC) something like:
1) Use the upstream service files whenever they exist.
2) Don't do anything Arch-specific, if possible. This will maximize
our chances of not having to change behavior in the future once the
service file is provided by upstream. In particular avoid
EnvironmentFile= especially if it points to the Arch-specific
/etc/conf.d/*.
Not using an EnvironmentFile= is ok if:
2a) either the daemon has its own configuration file where the same
settings can be specified.
2b) the default service file "just works" in the most common case.
Users who want to change the behavior should then override the default
service file.
If it is not possible to provide a sane default service file, I
suppose we should discuss it on a case-by-case basis.
A few comments about service files (assuming we just want to preserve
roughly the current behavior and not do anything fancy (if you want to
get fancy, I'll assume you know what you are doing)):
3) If your service requires the network to be configured before it
starts use After=network.target. Do not use
Wants/Requires=network.target.
4) Use Type=forking, unless you know it is not necessary. Most daemons
use double-forking to signal that they are ready, so to minimize the
chance of problems it is probably safest to use this mode. To make
sure that systemd is able to figure out which process is the main
process, it is best to tell the daemon to write a pidfile and point
systemd to it using PIDFile=. (If the daemon in question is dbus or
socket activated, that's a different matter, but I guess that is only
the case for the minority of daemons).
5) Our rc scripts do not support dependencies, but with systemd we
should add them where necessary. The most typical case is that A
requires the service B to be running before A is started. In that case
add Requires=B and After=B to A. If the dependency is optional then
add Wants=B and After=B instead. Dependencies are typically placed on
services and not on targets (see 3).
Example of a simple conversion:
rc script
=====
#!/bin/bash
. /etc/rc.conf
. /etc/rc.d/functions
case "$1" in
start)
stat_busy "Starting NIS Server"
/usr/sbin/ypserv
if [ $? -gt 0 ]; then
stat_fail
else
add_daemon ypserv
stat_done
fi
;;
stop)
stat_busy "Stopping NIS Server"
killall -q /usr/sbin/ypserv
if [ $? -gt 0 ]; then
stat_fail
else
rm_daemon ypserv
stat_done
fi
;;
restart)
$0 stop
sleep 1
$0 start
;;
*)
echo "usage: $0 {start|stop|restart}"
esac
systemd service file
============
[Unit]
Description=NIS/YP (Network Information Service) Server
Requires=rpcbind.service
After=network.target rpcbind.service
[Service]
Type=forking
PIDFile=/run/ypserv.pid
ExecStart=/usr/sbin/ypserv
[Install]
WantedBy=multi-user.target
More information about the arch-dev-public
mailing list