tsx-11.mit.edu
in
/pub/linux/docs/linux-standards/fsstnd/
.
Specific questions about following the standard may be
asked on debian-devel
, or referred to Daniel
Quinlan, the FSSTND coordinator, at
quinlan@pathname.com.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 FSSTND, section 4.8. However, you may create directories below them as you wish. You may not remove any of the directories listed in 4.8, 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 || truein the postinst script, and
rmdir /usr/local/lib/emacs/site-lisp && \ rmdir /usr/local/lib/emacs || \ truein 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.
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.
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 behaviour 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
behaviour.
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.
init
at boot time and when init
state (or `runlevel') is changed (see init(8)
).
These scripts are being 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
Smm/script or
Kmm/script
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
, and they
should accept one argument, saying what to do:
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 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
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/nulland 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)
.
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.
.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. (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
deinstalling 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.)
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 default >/dev/nullAnd in its postrm, to remove the links when the package is purged:
if [ purge = "$1" ]; then update-rc.d acct remove >/dev/null fi
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.monthlyAs these directory names say, the files within them are executed on a daily, weekly, or monthly basis, respectively.
If a certain job has to be executed more frequently than
`daily,' the package should install a file
/etc/cron.d/<package-name> tagged as
configuration file. This file uses the same syntax as
/etc/crontab and is processed by cron
automatically. (Note, that scripts 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.)
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 have to be registered as configuration file.
The scripts in these directories have to 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 the configuration files are kept on the system in this situation.
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 filesystem 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 behaviour 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.
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.
Here is a list that contains certain keys and their interpretation:
The following list explains how the different programs should be set up to achieve this:
This will solve the problem except for:
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.