The location of all installed files and directories must comply with the Linux
File system Hierarchy Standard (FHS). The latest version of this document can
be found alongside this manual or on http://www.pathname.com/fhs/
.[2] Specific questions about following
the standard may be asked on debian-devel
, or referred to Daniel
Quinlan, the FHS coordinator, at quinlan@pathname.com
.
As mandated by the FHS no package should place any files in
/usr/local, either by putting them in the file system archive to
be unpacked by dpkg
or by manipulating them in their maintainer
scripts.
However, the package should create empty directories below /usr/local so that the system administrator knows where to place site-specific files. These directories should be removed on package removal if they are empty.
Note, that this applies only to directories below /usr/local, not in /usr/local. The directory /usr/local itself may only contain the sub-directories listed in FHS, section 4.6. However, you may create directories below them as you wish. You may not remove any of the directories listed in 4.6, even if you created them.
Since /usr/local may be mounted read-only from a remote server,
these directories have to be created and removed by the postinst
and prerm maintainer scripts. These scripts must not fail if
either of these operations fail. (In the future, it will be possible to tell
dpkg
not to unpack files matching certain patterns, so that the
directories can be included in the .deb packages and system
administrators who do not wish these directories in /usr/local do not need to
have them.)
For example, the emacs
package will contain
mkdir -p /usr/local/lib/emacs/site-lisp || true
in the postinst script, and
rmdir /usr/local/lib/emacs/site-lisp && \ rmdir /usr/local/lib/emacs || \ true
in the prerm script.
If you do create a directory in /usr/local for local additions to a package, you must ensure that settings in /usr/local take precedence over the equivalents in /usr.
However, because '/usr/local' and its contents are for exclusive use of the local administrator, a package must not rely on the presence or absence of files or directories in '/usr/local' for normal operation.
The /usr/local directory itself and all the subdirectories created by the package should have permissions 2775 (group-writable and set-group-id) and be owned by root.staff.
The Debian system can be configured to use either plain or shadow passwords.
Some user ids (UIDs) and group ids (GIDs) are reserved globally for use by certain packages. Because some packages need to include files which are owned by these users or groups, or need the ids compiled into binaries, these ids must be used on any Debian system only for the purpose for which they are allocated. This is a serious restriction, and we should avoid getting in the way of local administration policies. In particular, many sites allocate users and/or local system groups starting at 100.
Apart from this we should have dynamically allocated ids, which should by default be arranged in some sensible order--but the behavior should be configurable.
No package except base-passwd may modify /etc/passwd, /etc/shadow, or /etc/group.
The UID and GID ranges are as follows:
Packages which need a single statically allocated uid or gid should use one of these; their maintainers should ask the base-passwd maintainer for ids.
adduser
will check for the existence of the user or
group, and if necessary choose an unused id based on the ranged specified in
adduser.conf.
adduser
will
choose UIDs and GIDs for user accounts in this range, though
adduser.conf may be used to modify this behavior.
These ids are for packages which are obscure or which require many
statically-allocated ids. These packages should check for and create the
accounts in /etc/passwd or /etc/group (using
adduser
if it has this facility) if necessary. Packages which are
likely to require further allocations should have a `hole' left after them in
the allocation, to give them room to grow.
The /etc/init.d directory contains the scripts executed by
init
at boot time and when init state (or `runlevel') is changed
(see init(8)
).
There are at least two different, yet functionally equivalent, ways of handling
these scripts. For the sake of simplicity, this document describes only the
symbolic link method. However, it may not be assumed that this method is being
used, and any manipulation of the various runlevel behaviours must be performed
using update-rc.d
as described below and not by manually
installing symlinks. For information on the implementation details of the
other method, implemented in the file-rc package, please refer to
the documentation of that package.
These scripts are 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, or `S' for the boot-up scripts.
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
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:
The start, stop, restart, and force-reload options must be supported by all scripts in /etc/init.d, the reload option is optional.
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
.
If a service reloads its configuration automatically (as in the case of
cron
, for example), the reload option of the
init.d script should behave as if the configuration has been
reloaded successfully.
These scripts should not fail obscurely when the configuration files remain but
the package has been removed, as configuration files remain on the system after
the package has been removed. Only when dpkg
is executed with the
--purge option will configuration files be removed. In
particular, the init script itself is usually a configuration file (see Notes, Section 3.3.5), and will remain on
the system if the package is removed but not purged. Therefore, you should
include a test statement at the top of the script, like this:
test -f program-executed-later-in-script || exit 0
A program is provided, update-rc.d
, to handle the it easier for
package maintainers to arrange for the proper creation and removal of
/etc/rcn.d symbolic links, or their functional
equivalent if another method is being used. This may be used by maintainers in
their packages' postinst and postrm scripts.
You should use this script to make changes to /etc/rcn.d and never either include any /etc/rcn.d symbolic links in the actual archive or manually create or remove the symbolic links in maintainer scripts. (The latter will fail if an alternative method of maintaining runlevel information is being used.)
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 either
running update-rc.d
, by simply adding, moving, or removing the
symbolic links in /etc/rcn.d if symbolic links are
being used, or by modifying /etc/runlevel.conf if the
file-rc method is being used.
To get the default behavior for your package, put in your postinst script
update-rc.d package defaults >/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)
.
There used to be another directory, /etc/rc.boot, which contained scripts which were run once per machine boot. This has been deprecated in favour of links from /etc/rcS.d to files in /etc/init.d as described in Introduction, Section 3.3.1. No packages may place files in /etc/rc.boot.
Do not include the /etc/rcn.d/* symbolic links
in the .deb file system 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, treat the /etc/init.d scripts as
configuration files, either by marking them as conffiles or managing them
correctly in the maintainer scripts (see Configuration files, Section 4.7). (This is important since we want
to give the local system administrator the chance to adapt the scripts to the
local system--e.g., to disable a service without de-installing the package, or
to specify some special command line options when starting a service--while
making sure her changes aren't lost during the next package upgrade.)
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 name server.
#!/bin/sh # # Original version by Robert Leslie # <rob@mars.org>, edited by iwj and cs test -x /usr/sbin/named || exit 0 case "$1" in start) echo -n "Starting domain name service: named" start-stop-daemon --start --quiet --exec /usr/sbin/named echo "." ;; stop) echo -n "Stopping domain name service: named" start-stop-daemon --stop --quiet \ --pidfile /var/run/named.pid --exec /usr/sbin/named echo "." ;; restart) echo -n "Restarting domain name service: named" start-stop-daemon --stop --quiet \ --pidfile /var/run/named.pid --exec /usr/sbin/named start-stop-daemon --start --verbose --exec /usr/sbin/named echo "." ;; force-reload|reload) echo -n "Reloading configuration of domain name service: named" start-stop-daemon --stop --signal 1 --quiet \ --pidfile /var/run/named.pid --exec /usr/sbin/named echo "." ;; *) echo "Usage: /etc/init.d/bind {start|stop|restart|reload|force-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 defaults >/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
Packages may not modify the configuration file /etc/crontab, nor may they modify the files in /var/spool/cron/crontabs.
If a package wants to install a job that has to be executed via cron, it should place a file with the name if the package in one of the following directories:
/etc/cron.daily /etc/cron.weekly /etc/cron.monthly
As these directory names imply, the files within them are executed on a daily, weekly, or monthly basis, respectively. The exact times are listed in /etc/crontab.
All files installed in any of these directories have to be scripts (shell scripts, Perl scripts, etc.) so that they can easily be modified by the local system administrator. In addition, they must be treated as configuration files.
If a certain job has to be executed more frequently than daily, the package
should install a file /etc/cron.d/package-name. This
file uses the same syntax as /etc/crontab and is processed by
cron
automatically. The file must also be treated as a
configuration file. (Note, that entries in the /etc/cron.d
directory are not handled by anacron
. Thus, you should only use
this directory for jobs which may be skipped if the system is not running.)
The scripts or crontab entries in these directories should check if all necessary programs are installed before they try to execute them. Otherwise, problems will arise when a package was removed but not purged since configuration files are kept on the system in this situation.
This section describes different formats for messages written to standard output by the /etc/init.d scripts. The intent is to improve the consistency of Debian's startup and shutdown look and feel.
Please look very careful at the details. We want to get the messages to look exactly the same way concerning spaces, punctuation, and case of letters.
Here is a list of overall rules that you should use when you create output messages. They can be useful if you have a non-standard message that isn't covered in the sections below.
I'm starting network daemons: nfsd mountd.
just say
Starting network daemons: nfsd mountd.
The following formats must be used
Use this format if your script starts one or more daemons. The output should look like this (a single line, no leading spaces):
Starting <description>: <daemon-1> <daemon-2> <...> <daemon-n>.
The <description> should describe the subsystem the daemon or set of daemons are part of, while <daemon-1> up to <daemon-n> denote each daemon's name (typically the file name of the program).
For example, the output of /etc/init.d/lpd would look like:
Starting printer spooler: lpd.
This can be achieved by saying
echo -n "Starting printer spooler: lpd" start-stop-daemon --start --quiet lpd echo "."
in the script. If you have more than one daemon to start, you should do the following:
echo -n "Starting remote file system services:" echo -n " nfsd"; start-stop-daemon --start --quiet nfsd echo -n " mountd"; start-stop-daemon --start --quiet mountd echo -n " ugidd"; start-stop-daemon --start --quiet ugidd echo "."
This makes it possible for the user to see what takes so long and when the final daemon has been started. Please be careful where to put spaces: In the example above the system administrator can easily comment out a line if he don't wants to start a specific daemon, while the displayed message still looks good.
If you have to set up different parameters of the system upon boot up, you can use this format:
Setting <parameter> to `<value>'.
You can use the following echo statement to get the quotes right:
echo "Setting DNS domainname to \`"value"'."
Note that the left quotation mark (`) is different from the right (').
When you stop a daemon you should issue a message similar to the startup message, except that `Starting' is replaced with `Stopping'.
So stopping the printer daemon will like like this:
Stopping printer spooler: lpd.
There a several examples where you have to run a program at system startup or shutdown to perform a specific task. For example, setting the system's clock via `netdate' or killing all processes when the system comes down. Your message should like this:
Doing something very useful...done.
You should print the `done.' right after the job has been completed, so that the user gets informed why he has to wait. You can get this behavior by saying
echo -n "Doing something very useful..." do_something echo "done."
in your script.
When a daemon is forced to reload its configuration files you should use the following format:
Reloading <daemon's-name> configuration...done.
If you have to print a message that doesn't fit into the styles described above, you can use something appropriate, but please have a look at the overall rules listed above.
Menu entries should follow the current menu policy as defined in the file
ftp.debian.org
in /debian/doc/package-developer/menu-policy.txt
or your local mirror. In addition, it is included in the
debian-policy package.
The Debian menu packages provides a unique interface between
packages providing applications and documents, and menu programs
(either X window managers or text-based menu programs as pdmenu
).
All packages that provide applications that need not be passed any special command line arguments for normal operation should register a menu entry for those applications, so that users of the menu package will automatically get menu entries in their window managers, as well in shells like pdmenu.
Please refer to the Debian Menu System document that comes with the menu package for information about how to register your applications and web documents.
Packages which provide the ability to view/show/play, compose, edit or print
MIME types should register themselves as such following the current MIME
support policy as defined in the file found on ftp.debian.org
in
/debian/doc/package-developer/mime_policy.txt
or your local mirror. In addition, it is included in the
debian-policy package.
MIME (Multipurpose Internet Mail Extensions, RFC 1521) is a mechanism for encoding files and data streams and providing meta-information about them, in particular their type (e.g. audio or video) and format (e.g. PNG, HTML, MP3).
Registration of MIME type handlers allows programs like mail user agents and web browsers to to invoke these handlers to view, edit or display MIME types they don't support directly.
To achieve a consistent keyboard configuration (i.e., all applications interpret a keyboard event the same way) all programs in the Debian distribution have to be configured to comply with the following guidelines.
Here is a list that contains certain keys and their interpretation:
The interpretation of any keyboard events should be independent of the terminal that's used, be it a virtual console, an X terminal emulator, an rlogin/telnet session, etc.
The following list explains how the different programs should be set up to achieve this:
This will solve the problem except for:
No program may depend on environment variables to get reasonable defaults. (That's because these environment variables would have to be set in a system-wide configuration file like /etc/profile, which is not supported by all shells.)
If a program should depend on environment variables for its configuration, the program has to be changed to fall back to a reasonable default configuration if these environment variables are not present. If this cannot be done easily (e.g., if the source code of a non-free program is not available), the program should be replaced by a small `wrapper' shell script which sets the environment variables and calls the original program.
Here is an example of a wrapper script for this purpose:
#!/bin/sh BAR=/var/lib/fubar export BAR exec /usr/lib/foo/foo "$@"
Furthermore, as /etc/profile is a configuration file of the
bash
package, no other package may put any environment variables
or other commands into that file.
ijackson@gnu.ai.mit.edu
schwarz@debian.org
bweaver@debian.org
debian-policy@lists.debian.org