dpkg programmers' manual - chapter 13
Configuration of init


13.1 Introduction to the init.d scheme

The /etc/init.d directory contains the scripts executed by init when init state (or `runlevel') is changed (see init(8)).

These scripts are be referenced by symbolic links in the /etc/rcn.d directories. When changing runlevels, init looks in the directory /etc/rcn.d for the scripts it should execute, where n is the runlevel that is being changed to.

The names of the links all have the form Smmscript or Kmmscript where mm is a two-digit number and script is the name of the script (this should be the same as the name of the actual script in /etc/init.d. When init changes runlevel first the targets of the links whose names starting with a K are executed, each with the single argument stop, followed by the scripts prefixed with an S, each with the single argument start. The K links are responsible for killing services and the S link for starting services upon entering the runlevel.

For example, if we are changing from runlevel 2 to runlevel 3, init will first execute all of the K prefixed scripts it finds in /etc/rc3.d, and then all of the S prefixed scripts. The links starting with K will cause the referred-to file to be executed with an argument of stop, and the S links with an argument of start.

The two-digit number mm is used to decide which order to start and stop things in - low-numbered links have their scripts run first. For example, the K20 scripts will be executed before the K30 scripts. This is used when a certain service must be started before another. For example, the name server bind might need to be started before the news server inn so that inn can set up its access lists. In this case, the script that starts bind should have a lower number than the script that starts inn so that it runs first:

/etc/rc2.d/S17bind
/etc/rc2.d/S70inn

13.2 Writing init.d scripts

Packages can and should place scripts in /etc/init.d to start or stop services at boot time or during a change of runlevel. These scripts should be named /etc/init.d/package, and they should accept one argument, saying what to do: start, meaning to starts the service, or stop, to stop the service. Optionally they can support reload which causes the configuration to be reloaded.

The init.d scripts should ensure that they will behave sensibly if invoked with start when the service is already running, or with stop when it isn't, and that they don't kill unfortunately-named user processes. The best way to achieve this is usually to use start-stop-daemon.

These scripts should not fail obscurely when the configuration files remain but the package has been removed, as the default in dpkg is to leave configuration files on the system after the package has been removed. Only when it is executed with the --purge option will dpkg remove configuration files. Therefore, you should include a test statement at the top of the script, like this:

test -f program-executed-later-in-script || exit 0

13.3 Managing the rcn.d links - update-rc.d

A program is provided, update-rc.d, to make it easier for package maintainers to arrange for the proper creation and removal of /etc/rcn.d symbolic links from their postinst and postrm scripts.

You should use this script to make changes to /etc/rcn.d and never include any /etc/rcn.d symbolic links in the actual archive.

By default update-rc.d will start services in each of the multi-user state runlevels (2, 3, 4, and 5) and stop them in the halt runlevel (0), the single-user runlevel (1) and the reboot runlevel (6). The system administrator will have the opportunity to customize runlevels by simply adding, moving, or removing the symbolic links in /etc/rcn.d.

To get the default behaviour for your package, put in your postinst script

update-rc.d package default >/dev/null
and in your postrm
if [ purge = "$1" ]; then
    update-rc.d package remove >/dev/null
fi

This will use a default sequence number of 20. If it does not matter when or in which order the script is run, use this default. If it does, then you should talk to the maintainer of the sysvinit package or post to debian-devel, and they will help you choose a number.

For more information about using update-rc.d, please consult its manpage update-rc.d(8).


13.4 Boot-time initialisation - rc.boot

There is another directory, /etc/rc.boot, which contains scripts which are run once per machine boot. This facility is provided for initialisation of hardware devices, cleaning up of leftover files, and so forth.

For example, the kbd package provides a script here for initialising the keyboard layout and console font and mode.

The files in /etc/rc.boot should not be links into /etc/init.d - they should be the scripts themselves.

rc.boot should not be used for starting general-purpose daemons and similar activities. This should be done using the rcn.d scheme, above, so that the services can be started and stopped cleanly when the runlevel changes or the machine is to be shut down or rebooted.


13.5 Notes

Do not include the /etc/rcn.d/* symbolic links in the .deb filesystem archive! This will cause problems! You should create them with update-rc.d, as above.

Do not include the /etc/rcn.d/* symbolic links in dpkg's conffiles list! This will cause problems! Do, however, include the /etc/init.d scripts in conffiles.


13.6 Example

The bind DNS (nameserver) package wants to make sure that the nameserver is running in multiuser runlevels, and is properly shut down with the system. It puts a script in /etc/init.d, naming the script appropriately bind. As you can see, the script interprets the argument reload to send the nameserver a HUP signal (causing it to reload its configuration); this way the user can say /etc/init.d/bind reload to reload the nameserver.

#!/bin/sh
# Original version by Robert Leslie <rob@mars.org>, edited by iwj
test -x /usr/sbin/named || exit 0
case "$1" in
  start)
    test -f /etc/named.boot -a -f /var/named/boot.options || exit 0
    start-stop-daemon --start --verbose --exec /usr/sbin/named
    ;;
  stop)
    start-stop-daemon --stop --verbose  \
        --pidfile /var/run/named.pid --exec /usr/sbin/named
    ;;
  reload)
    start-stop-daemon --stop --signal 1 --verbose  \
        --pidfile /var/run/named.pid --exec /usr/sbin/named
    ;;
  *)
    echo "Usage: /etc/init.d/bind {start|stop|reload}" >&2
    exit 1
    ;;
esac
exit 0

Another example on which to base your /etc/init.d scripts is in /etc/init.d/skeleton.

If this package is happy with the default setup from update-rc.d, namely an ordering number of 20 and having named running in all runlevels, it can say in its postinst:

update-rc.d bind default >/dev/null
And in its postrm, to remove the links when the package is purged:
if [ purge = "$1" ]; then
     update-rc.d acct remove >/dev/null
fi

dpkg programmers' manual - Copyright ©1996 Ian Jackson.
Contents; abstract; next; back.
20 August 1996
Ian Jackson ijackson@gnu.ai.mit.edu