diff --git a/docs/manual/adding-packages-directory.adoc b/docs/manual/adding-packages-directory.adoc index cb19f3bac9..44852afa04 100644 --- a/docs/manual/adding-packages-directory.adoc +++ b/docs/manual/adding-packages-directory.adoc @@ -576,23 +576,120 @@ name. The +NN+ is the start order number which needs to be carefully chosen. For example, a program that requires networking to be up should not start before +S40network+. The scripts are started in alphabetical order, so +S01syslogd+ starts before +S01watchdogd+, and +S02sysctl+ -start thereafter. +starts thereafter. [source,sh] ---- include::S01syslogd[] ---- -*Note:* programs that support reloading their configuration in some -fashion (+SIGHUP+) should provide a +reload()+ function similar to -+stop()+. The +start-stop-daemon+ command supports +--stop --signal -HUP+ for this. It is recommended to always append +--exec -"/sbin/$DAEMON"+ to all +start-stop-daemon+ commands to ensure signals -are set to a PID that matches +$DAEMON+. +Scripts should use long form options where possible for clarity. -Both start scripts and unit files can source command line arguments from -+/etc/default/foo+, in general, if such a file does not exist it should -not block the start of the daemon, unless there is some site specirfic -command line argument the daemon requires to start. For start scripts a -+FOO_ARGS="-s -o -m -e -args"+ can be defined to a default value in and -the user can override this from +/etc/default/foo+. +==== Start script configuration + +Both start scripts and unit files can source command line arguments +from +/etc/default/foo+, where +foo+ is the daemon name as set in the ++DAEMON+ variable. In general, if such a file does not exist it should +not block the start of the daemon, unless there is some site specific +command line argument the daemon requires to start. For start scripts ++FOO_ARGS="-s -o -m -e -args"+ can be defined to a default value in +the script, and the user can override this from +/etc/default/foo+. + +==== Handling the PID file + +A PID file is needed to keep track of what the main process of a +service is. How to handle it depends on whether the service creates +its own PID file, and if it deletes it on shutdown. + +* If your service doesn't create its own PID file, invoke the daemon + in foreground mode, and use +start-stop-daemon --make-pidfile + --background+ to let +start-stop-daemon+ create the PID file. See + +S01syslogd+ for example: ++ +[source,sh] +---- +start-stop-daemon --start --background --make-pidfile \ + --pidfile "$PIDFILE" --exec "/sbin/$DAEMON" \ + -- -n $SYSLOGD_ARGS +---- + +* If your service creates its own PID file, pass the +--pidfile+ + option to both +start-stop-daemon+ *and the daemon itself* (or set + it appropriately in a configuration file, depending on what the + daemon supports) so they agree on where the PID file is. See + +S45NetworkManager+ for example: ++ +[source,sh] +---- +start-stop-daemon --start --pidfile "$PIDFILE" \ + --exec "/usr/sbin/$DAEMON" \ + -- --pid-file="$PIDFILE" $NETWORKMANAGER_ARGS +---- + +* If your service removes its PID file on shutdown, use a loop testing + that the PID file has disappeared on stop, see +S45NetworkManager+ + for example: ++ +[source,sh] +---- +while [ -f "$PIDFILE" ]; do + sleep 0.1 +done +---- + +* If your service doesn't remove its PID file on shutdown, use a loop + with +start-stop-daemon+ checking if the service is still running, + and delete the PID file after the process is gone. See +S01syslogd+ + for example: ++ +[source,sh] +---- +while start-stop-daemon --stop --test --quiet --pidfile "$PIDFILE" \ + --exec "/sbin/$DAEMON"; do + sleep 0.1 +done +rm -f "$PIDFILE" +---- ++ +Note the +--test+ flag, which tells +start-stop-daemon+ to not +actually stop the service, but test if it would be possible to, which +fails if the service is not running. + +==== Stopping the service + +The stop function should check that the daemon process is actually +gone before returning, otherwise restart might fail because the new +instance is started before the old one has actually stopped. How to do +that depends on how the PID file for the service is handled (see +above). It is recommended to always append +--exec "/sbin/$DAEMON"+ to +all +start-stop-daemon+ commands to ensure signals are sent to a PID +that matches +$DAEMON+. + +==== Reloading service configuration + +Programs that support reloading their configuration in some fashion +(e.g. +SIGHUP+) should provide a +reload()+ function similar to ++stop()+. The +start-stop-daemon+ command supports +--stop --signal +HUP+ for this. When sending signals this way, whether SIGHUP or +others, make sure to use the symbolic names and not signal +numbers. Signal numbers can vary between CPU architectures, and names +are also easier to read. + +==== Return codes + +The action functions of the start script should return a success (or +failure) code, usually the return code of the relevant +start-stop-daemon action. The last one of those should be the return +code of the start script as a whole, to allow automatically checking +for success, e.g. when calling the start script from other +scripts. Note that without an explicit +return+ the return code of the +last command in a script or function becomes its return code, so an +explicit return is not always necessary. + +==== Logging + +When a service forks to the background, or +start-stop-daemon +--background+ does that, stdout and stderr are generally closed, and +anything log messages the service may write there get lost. If +possible, configure your service to log to syslog (preferably), or a +dedicated log file.