Translation(s): none

How to LSBize an Init Script

Note: Debian discontinued LSB support in 2015, see DebianLsb and for example Debian dropping the Linux Standard Base. This does not affect the Debian requirement to include LSB style dependency information in the init.d scripts used by non-systemd installations.

A status page for dependency based boot sequencing is available.

This is a short documentation about how to make an Init Script LSB (Linux Standard Base)-compliant based on the Chapter 20 of the LSB 3.1.

LSB-compliant init scripts need to:

and should also follow Debian Policy, chapter 9.4 Console messages from init.d scripts)

Full information on the actions (and return codes) that LSB scripts have to honor are available at LSB 3.1, Chapter 20.2. Init Script Actions. Maintainers should review that section and review / adjust their init.d scripts accordingly.

Run-time dependencies

Adding run-time dependencies was a release goal for Lenny, and dependency based boot sequencing is the default in Squeeze. There is a separate wiki page documenting that effort.

By documenting the run-time dependencies for init.d scripts, it becomes possible to verify the current boot order, order the boot using these dependencies, and run boot scripts in parallel to speed up the boot process.

Add a block like this in the init.d script:

# Provides:          scriptname
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start daemon at boot time
# Description:       Enable service provided by daemon.

The block shown above has a special rigid format delimited by the lines


where all trailing spaces shall be ignored. On the other hand, all lines inside the block shall be of the form

# {keyword}: arg1 [arg2...]

and begin with a hash character '#' in the first column followed by one single space, except for the lines following the Description keyword. The following keywords are defined

Provides: boot_facility_1 [boot_facility_2...]

Required-Start: boot_facility_1 [boot_facility_2...]

Required-Stop: boot_facility_1 [boot_facility_2...]

Should-Start: boot_facility_1 [boot_facility_2...]

Should-Stop: boot_facility_1 [boot_facility_2...]

Default-Start: run_level_1 [run_level_2...]

Default-Stop: run_level_1 [run_level_2...]

Short-Description: short_description

Description: multiline_description

X-Start-Before: boot_facility_1 [boot_facility_2...]

X-Stop-After: boot_facility_1 [boot_facility_2...]

X-Interactive: true

For dependency tracking, the provides, required- and should- keywords are important, and the rest is unused. The default runlevels are used by a program to order the init scripts (e.g. insserv) to keep track of which rc#.d directory to update when a service is added for the first time, and should reflect the intent of the service.

There are some "virtual" facility names, listed in the [LSB 3.1]. These are:


all local filesystems are mounted. All scripts that write in /var/ need to depend on this, unless they already depend on $remote_fs.


low level networking (ethernet card; may imply PCMCIA running)


daemons which may provide hostname resolution (if present) are running. For example, daemons to query DNS, NIS+, or LDAP.


daemons providing ?SunRPC/ONCRPC portmapping service as defined in RFC 1833 (if present) are running all remote


all filesystems are mounted. In some LSB run-time environments, filesystems such as /usr may be remote. If the script need a mounted /usr/, it needs to depend on $remote_fs. Scripts depending on $remote_fs do not need to depend on $local_fs. During shutdown, scripts that need to run before sendsigs kills all processes should depend on $remote_fs.


system logger is operational


the system time has been set, for example by using a network-based time program such as ntp or rdate, or via the hardware Real Time Clock. Note that just depending on ntp will not result in an accurate time just after ntp started. It usually takes minutes until ntp actually adjusts the time. Also note that standard insserv.conf just lists hwclock as $time.


facility supported by insserv to start a script after all the scripts not depending on $all, at the end of the boot sequence. This only work for start ordering, not stop ordering. Depending on a script depending on $all will give incorrect ordering, as the script depending on $all will be started after the script depending on it.

Other (non-system) facilities may be defined by other applications. These facilities shall be named using the same conventions defined for naming init scripts. See the list of proposed Debian specific virtual facilities for more information on this.

Most of this section was originally based from a message by Petter Reinholdtsen on Debian-devel.

BTS reports related to LSB headers are usertagged.

Frequent questions

Is it possible to start a given init script as late as possible?

yes, if you really want to do so, insserv recognises the $all virtual facility name such that the script will be executed at the end.

Is it possible to add extra keywords?
If there is no current keyword you could use for your needs, the LSB allows for local extensions using the prefix X-. For example, X-Debian-foobardecl or X-Ubuntu-fastdecl.
Is it possible to specify that a given script should start before another script?

There is no such standard-defined header, but there is a proposed extention implemented in the insserv package (since version 1.09.0-8). Use the X-Start-Before and X-Stop-After headers proposed by ?SuSe.

Shouldn't I wait until the Debian policy changes?

The Debian policy changes are slow to introduce even for things (for an example, see #291148) which most maintainers agree are good since we have to wait first for many packages to do things in the same way before turning it into policy. Since we want to be LSB compliant, init.d scripts can be adjusted now to be LSB compliant.

What is a "proper" exit status code?

Looking at #208010, this seems rather controversial. Non-zero exit codes might even cause breakage, and the LSB conflicts with Debian policy here.