After a script has been written, it needs to be integrated
into rc.d
. The crucial step is to install
the script in /etc/rc.d
(for the base
system) or /usr/local/etc/rc.d
(for
ports). Both <bsd.prog.mk
> and
<bsd.port.mk
> provide convenient
hooks for that, and usually you do not have to worry about
the proper ownership and mode. System scripts should be
installed from src/etc/rc.d
through the
Makefile
found there. Port scripts can
be installed using USE_RC_SUBR
as described
in
the Porter's Handbook.
However, we should consider beforehand the place of our script in the system startup sequence. The service handled by our script is likely to depend on other services. For instance, a network daemon cannot function without the network interfaces and routing up and running. Even if a service seems to demand nothing, it can hardly start before the basic filesystems have been checked and mounted.
We mentioned rcorder(8) already. Now it is time to
have a close look at it. In a nutshell, rcorder(8) takes
a set of files, examines their contents, and prints a
dependency-ordered list of files from the set to
stdout
. The point is to keep dependency
information inside the files so that
each file can speak for itself only. A file can specify the
following information:
the names of the “conditions” (which means services to us) it provides;
the names of the “conditions” it requires;
the names of the “conditions” this file should run before;
additional keywords that can be used to select a subset from the whole set of files (rcorder(8) can be instructed via options to include or omit the files having particular keywords listed.)
It is no surprise that rcorder(8) can handle only text files with a syntax close to that of sh(1). That is, special lines understood by rcorder(8) look like sh(1) comments. The syntax of such special lines is rather rigid to simplify their processing. See rcorder(8) for details.
Besides using rcorder(8) special lines, a script can insist on its dependency upon another service by just starting it forcibly. This can be needed when the other service is optional and will not start by itself because the system admin has disabled it mistakenly in rc.conf(5).
With this general knowledge in mind, let us consider the simple daemon script enhanced with dependency stuff:
#!/bin/sh # PROVIDE: mumbled oldmumble # REQUIRE: DAEMON cleanvar frotz # BEFORE: LOGIN # KEYWORD: nojail shutdown . /etc/rc.subr name=mumbled rcvar=mumbled_enable command="/usr/sbin/${name}" start_precmd="${name}_prestart" mumbled_prestart() { if ! checkyesno frotz_enable && \ ! /etc/rc.d/frotz forcestatus 1>/dev/null 2>&1; then force_depend frotz || return 1 fi return 0 } load_rc_config $name run_rc_command "$1"
As before, detailed analysis follows:
That line declares the names of “conditions” our script provides. Now other scripts can record a dependency on our script by those names. Note:Usually a script specifies a single condition provided. However, nothing prevents us from listing several conditions there, e.g., for compatibility reasons. In any case, the name of the main, or the only,
| |
So our script indicates which “conditions”
provided by other scripts it depends on. According to
the lines, our script asks rcorder(8) to put it after
the script(s) providing Note:The Besides conditions corresponding to a single service
each, there are meta-conditions and their
“placeholder” scripts used to ensure that
certain groups of operations are performed before others.
These are denoted by
Keep in mind that putting a service name in the
| |
As we remember from the above text,
rcorder(8) keywords can be used to select or leave
out some scripts. Namely any rcorder(8) consumer
can specify through In FreeBSD, rcorder(8) is used by
| |
To begin with,
If you still cannot do without
|
All FreeBSD documents are available for download at http://ftp.FreeBSD.org/pub/FreeBSD/doc/
Questions that are not answered by the
documentation may be
sent to <[email protected]>.
Send questions about this document to <[email protected]>.