RC(8) | System Manager's Manual | RC(8)

# NAME

`rc`, `rc.local`, `rc.shutdown`, `rc.shutdown.final`, `rc.d/` — startup and shutdown scripts

# SYNOPSIS

`rc` |

`rc.local` |

`rc.shutdown` |

`rc.d/` |

# DESCRIPTION

`rc` is the command script which controls the startup of various services, and is invoked by init(8) as part of the process of entering the automatic reboot to multi-user startup, or after the single user mode shell has exited. If init(8) is starting the automatic reboot process, `rc` is invoked with the argument of ‘autoboot’.

`rc.local` is a command script to which local boot-time actions can be added. It is (nearly) the last thing invoked by `rc` during a normal boot.

`rc.shutdown` is the command script which shuts down various services, and is invoked by shutdown(8) as part of the process of shutting down the system.

`rc.d/` is the directory which contains various sh(1) scripts, one for each service, which are called by `rc` at startup, `rc.shutdown` at shutdown, and as necessary during system operation to stop, start, restart, reload, or otherwise control the service.

## Operation of rc

1. Source /etc/rc.subr to load various rc.subr(8) shell functions to use.
2. If autobooting, set autoboot=yes and enable a flag (rc_fast=yes), which prevents the `rc.d` scripts from performing the check for already running processes (thus speeding up the boot process). This rc_fast=yes speedup won't occur when `rc` is started up after exiting the single-user shell.
3. Invoke rcorder(8) to order the files in /etc/rc.d/ that do not have a “nostart” keyword (refer to rcorder(8)'s `-s` flag), and assigns the result to a variable.
4. Calls each script in turn using `run_rc_script`() (from rc.subr(8)), which sets `$1` to ‘start’, and sources the script in a sub-shell. If the script has a ‘.sh’ suffix then it is sourced directly into the current shell.
5. The output from the above steps is sent to a post-processor. If rc_silent is false, then the post-processor displays the output. If rc_silent is true, then the post-processor invokes the command specified in rc_silent_cmd once for each line, without otherwise displaying the output. Useful values for rc_silent_cmd include “:” to display nothing at all, and “twiddle” to display a spinning symbol on the console. Regardless of the value of rc_silent, the post-processor saves the output in /var/run/rc.log.

## Operation of rc.shutdown

1. Source /etc/rc.subr to load various rc.subr(8) shell functions to use.
2. Invoke rcorder(8) to order the files in /etc/rc.d/ that have a “shutdown” keyword (refer to rcorder(8)'s `-k` flag), reverses that order, and assigns the result to a variable.
3. Calls each script in turn using `run_rc_script`() (from rc.subr(8)), which sets `$1` to ‘stop’, and sources the script in a sub-shell. If the script has a ‘.sh’ suffix then it is sourced directly into the current shell.
4. Runs /etc/rc.shutdown.final if it exists, passing the currently ongoing shutdown action, which will be one of:
   - shutdown when going to single user mode.
   - halt when halting the machine (but not powering it down).
   - reboot when rebooting the machine.
   - poweroff when halting the machine and powering it off.

   The script may be used to control additional actions, e.g. powering off external devices, restarting a UPS (in case main power is restored in the interval betweeen the computer powering off and the UPS running out of battery).

## Contents of rc.d/

`rc.d/` is located in /etc/rc.d. The following file naming conventions are currently used in `rc.d/`:

ALLUPPERCASE
  Scripts that are ‘placeholders’ to ensure that certain operations are performed before others. In order of startup, these are:
  NETWORKING
    Ensure basic network services are running, including general network configuration (network) and dhcpcd.
  SERVERS
    Ensure basic services (such as NETWORKING, ppp, syslogd, and kdc) exist for services that start early (such as named), because they're required by DAEMON below.
  DAEMON
    Before all general purpose daemons such as dhcpd, lpd, and ntpd.
  LOGIN
    Before user login services (inetd, telnetd, rshd, sshd, and xdm), as well as before services which might run commands as users (cron, postfix, and sendmail).
inline.sh
  Scripts that are sourced into the current shell rather than a sub-shell have a ‘.sh’ suffix. Extreme care must be taken in using this, as the startup sequence will terminate if the script causes the current shell process to terminate. /etc/rc.d/bootconf.sh uses this behaviour to allow the user to select a different configuration (including /etc/rc.conf) early in the boot.
service
  Scripts that are sourced in a sub-shell. The boot does not stop if such a script terminates with a non-zero status, but a script can stop the boot if necessary by invoking the `stop_boot`() function (from rc.subr(8)).

Each script should contain rcorder(8) keywords, especially an appropriate “PROVIDE” entry.

The scripts are expected to support at least the following arguments:

start
  Start the service. This should check that the service is to be started as specified by rc.conf(5). Also checks if the service is already running and refuses to start if it is. This latter check is not performed by standard NetBSD scripts if the system is starting directly to multi-user mode, to speed up the boot process.
stop
  If the service is to be started as specified by rc.conf(5), stop the service. This should check that the service is running and complain if it's not.
restart
  Perform a stop then a start.
status
  If the script starts a process (rather than performing a one-off operation), show the status of the process. Otherwise it's not necessary to support this argument. Defaults to displaying the process ID of the program (if running).
poll
  If the script starts a process (rather than performing a one-off operation), wait for the command to exit. Otherwise it's not necessary to support this argument.
rcvar
  Display which rc.conf(5) variables are used to control the startup of the service (if any).

Other arguments (such as ‘reload’, ‘dumpdb’, etc) can be added if necessary.

The argument may have one of the following prefixes to alter its operation:

fast
  Skip the check for an existing running process. Sets rc_fast=yes.
force
  Skips the rc.conf(5) check, ignores a failure result from any of the prerequisite checks, executes the command, and always returns a zero exit status. Sets rc_force=yes.
one
  Skips the rc.conf(5) check, but performs all other prerequisite tests.

In order to simplify scripts, the `run_rc_command`() function from rc.subr(8) may be used.

# FILES

/etc/rc
  Startup script called by init(8).
/etc/rc.d/
  Directory containing control scripts for each service.
/etc/rc.local
  Local startup script.
/etc/rc.shutdown
  Shutdown script called by shutdown(8).
/etc/rc.subr
  Contains rc.subr(8) functions used by various scripts.
/etc/rc.conf
  System startup configuration file.
/var/run/rc.log
  Log file created by `rc`.

# SEE ALSO

rc.conf(5), init(8), rc.subr(8), rcorder(8), reboot(8), shutdown(8)

Luke Mewburn, The Design and Implementation of the NetBSD rc.d system, Proceedings of the FREENIX Track: 2001 USENIX Annual Technical Conference, USENIX Association, http://www.usenix.org/publications/library/proceedings/usenix01/freenix01/full_papers/mewburn/mewburn.pdf, June 25-30, 2001.

# HISTORY

The `rc` command appeared in 4.0BSD. The /etc/rc.d support was implemented in NetBSD 1.5 by Luke Mewburn ⟨lukem@NetBSD.org⟩. The post-processor, support for rc_silent, and saving output to a file, was implemented in NetBSD 6.0 by Alan Barrett.

December 7, 2024 | NetBSD 11.0