The FreeBSD init system is rc.d, which was adopted from NetBSD. rc.d is based on the traditional BSD init (incorporates some ideas from SystemV init). rc.d has these improvements over the old init system:
/etc/rc/
script./etc/rc
and /etc/rc.conf
.At boot, /sbib/init
runs as the first process. It spawns /bin/sh
to run /etc/rc
. The /etc/rc
script checks and mounts filesystems, starts daemons, runs /etc/netstart
, and finally starts any local services from /etc/rc.local
. After /etc/rc
completes, init forks a copy of itself for each tty.
At shutdown, init simply sends SIGHUP to each process, waits ten seconds for the processes to clean themselves up, sends SIGNTERM and waits ten seconds, and finally sends SIGKILL to each remaining process.
SVR4 init.d, like that used by Solaris, is built around the concept of run levels. /sbin/init
runs at boot, and launches /sbin/init
. /sbin/init
runs /etc/inittab
, which points to directories of scripts for each run level. For example, /etc/rc1.d/
starts everything for single-user mode, /etc/rc3.d/
has scripts for all the nulti-user stuff including NFS, and /etc/rc5.d
contains all the shutdown scripts. These scripts are normally symlinks to scripts in /etc/init.d/
.
Because services are started with individual scripts, it’s easy for an administrator to restart a service like /etc/init.d/foo restart
. Services can be enabled or disabled by adding or removing the script from the /etc/rcN.d/
directory.
Some init.d systems have /etc/rcN.d/Sfoo
and /etc/rcN.d/Kfoo
scripts to start and stop services each time run level N is entered or exited.
On boot, init runs /etc/rc
. /etc/rc
asks rcorder
to order and resolve dependencies for any scripts in /etc/rc.d/
(except for scripts marked ‘nostart’). /etc/rc
runs each script returned by rcorder
with a ‘start’ argument.
File | Purpose |
---|---|
/etc/rc | System start-up |
/etc/rc.shutdown | System shutdown script |
/etc/rc.d/* | Individual service start-up scripts |
/etc/rc.subr | Common shell code reused by rc scripts |
/etc/defaults/rc.conf | Default options |
/etc/rc.conf | System options |
/etc/rc.conf.d/* | Per-service configs |
/etc/rc.conf
allows administrators to easily specity which services should be started and their basic flags, like:
foo_enable="YES"
foo_option="bar"
The settings in /etc/rc.conf
override the defaults in /etc/defaults/rc.conf
.
/etc/rc.shutdown
gets runs before init sends SIGHUP to everything. This allows ordered shutdown of certain services (e.g. stop a front-end service before shutting down its back-end database). The shutdown order is resolved by rcorder
, but in the opposite order as start-up.
Administrators can control services easily by calling individual scripts like /etc/rc.d/foo restart
.
To see the order in which services will be started:
% rcorder /etc/rc.d/* /usr/local/etc/rc.d/*
Scripts in /etc/rc.d/
all support ‘start’ and ‘stop’ arguments. Some also support ‘restart’, ‘status’, and ‘rcvar’ (which shows any /etc/rc.conf
variables that can be set for it).
% /usr/local/etc/rc.d/sshguard status
sshguard is running as pid 624.
% /usr/local/etc/rc.d/sshguard rcvar
# sshguard
#
sshguard_enable="YES"
# (default: "")
The ‘onestart’ argument can be used to manually activate a service that is not enabled at boot by /etc/rc.conf
:
% /etc/rc.d/foo onestart
(‘onestart’ is safer than ‘forcestart’. ‘forcestart’ skips prerequisite checks and ignores errors.)
See the examples in /etc/rc.d/
and rc(8).
Scripts must be written for /bin/sh
.
Place the script in /usr/local/etc/rc.d/
. Remember to make the script executable.
A commented example:
#!/bin/sh
# These directives are parsed by `rcorder`.
# The PROVIDE line names how other scripts can REQUIRE this service:
# PROVIDE: foo
# Run this service after those REQUIREd. ALLUPPERCASE placeholders are described in rc(8). BEFORE also exists, but should be used with caution.
# REQUIRE: NETWORKING bar
# Keywords include:
# - 'nojail': don't run in jail environments
# - 'nostart': don't start or only start manually
# - 'shutdown': run service shutdown function before init starts generally sending SIGHUP to everything
# KEYWORD: shutdown
# Include common rc.d functions:
. /etc/rc.subr
# Note that some network-related function are in `/etc/network.subr`.
# 'name' is mandatory:
name='foo'
# Set name of on/off knob for `/etc/rc.conf`:
rcvar=foo_enable
command="/usr/local/bin/foo"
# Argument added after $foo_flags (don't include flags here):
command_args="my arguments > /dev/null 2>&1"
pidfile="/var/run/${name}.pid"
# Require files to exist before daemon runs.
# required_dirs and required_vars (environmental variables) also can be defined.
# forcestart skips these requirements.
required_files="/usr/local/etc/foo.conf"
# Load the rc.conf variables:
load_rc_config $name
# run_rc_command will complain if rcvar is set and the knob value is not set:
: ${foo_enable:=no}
: ${foo_msg="Not started."}
start_cmd="${name}_start"
# Override stop with no-op, since we are just echoing and exiting:
stop_cmd=":"
foo_start()
{
echo "$foo_msg"
}
# Usually the last command of an rc.d script:
run_rc_cmd "$1"