Index: head/etc/rc.d/fsck =================================================================== --- head/etc/rc.d/fsck (revision 169667) +++ head/etc/rc.d/fsck (revision 169668) @@ -1,90 +1,79 @@ #!/bin/sh # # $NetBSD: fsck,v 1.2 2001/06/18 06:42:35 lukem Exp $ # $FreeBSD$ # # PROVIDE: fsck # REQUIRE: localswap # KEYWORD: nojail . /etc/rc.subr name="fsck" start_cmd="fsck_start" stop_cmd=":" -stop_boot() -{ - # Terminate the process (which may include the parent /etc/rc) - # if booting directly to multiuser mode. - # - if [ "$autoboot" = yes ]; then - kill -TERM $$ - fi - exit 1 -} - fsck_start() { if [ "$autoboot" = no ]; then echo "Fast boot: skipping disk checks." elif [ ! -r /etc/fstab ]; then echo "Warning! No /etc/fstab: skipping disk checks." elif [ "$autoboot" = yes ]; then # During fsck ignore SIGQUIT trap : 3 echo "Starting file system checks:" if checkyesno background_fsck; then fsck -F -p else fsck -p fi case $? in 0) ;; 2) stop_boot ;; 4) echo "Rebooting..." reboot echo "Reboot failed; help!" stop_boot ;; 8) if checkyesno fsck_y_enable; then echo "File system preen failed, trying fsck -y." fsck -y case $? in 0) ;; *) echo "Automatic file system check failed; help!" stop_boot ;; esac else echo "Automatic file system check failed; help!" stop_boot fi ;; 12) echo "Boot interrupted." stop_boot ;; 130) stop_boot ;; *) echo "Unknown error; help!" stop_boot ;; esac fi } load_rc_config $name run_rc_command "$1" Index: head/etc/rc.d/ipsec =================================================================== --- head/etc/rc.d/ipsec (revision 169667) +++ head/etc/rc.d/ipsec (revision 169668) @@ -1,68 +1,60 @@ #!/bin/sh # # $NetBSD: ipsec,v 1.7 2002/03/22 04:33:58 thorpej Exp $ # $FreeBSD$ # # PROVIDE: ipsec # REQUIRE: FILESYSTEMS # BEFORE: DAEMON mountcritremote # KEYWORD: nojail . /etc/rc.subr name="ipsec" rcvar=`set_rcvar` start_precmd="ipsec_prestart" start_cmd="ipsec_start" stop_precmd="test -f $ipsec_file" stop_cmd="ipsec_stop" reload_cmd="ipsec_reload" extra_commands="reload" ipsec_program="/sbin/setkey" # ipsec_file is set by rc.conf ipsec_prestart() { if [ ! -f "$ipsec_file" ]; then warn "$ipsec_file not readable; ipsec start aborted." - # - # If booting directly to multiuser, send SIGTERM to - # the parent (/etc/rc) to abort the boot - # - if [ "$autoboot" = yes ]; then - echo "ERROR: ABORTING BOOT (sending SIGTERM to parent)!" - kill -TERM $$ - exit 1 - fi + stop_boot return 1 fi return 0 } ipsec_start() { echo "Installing ipsec manual keys/policies." ${ipsec_program} -f $ipsec_file } ipsec_stop() { echo "Clearing ipsec manual keys/policies." # still not 100% sure if we would like to do this. # it is very questionable to do this during shutdown session, since # it can hang any of remaining IPv4/v6 session. # ${ipsec_program} -F ${ipsec_program} -FP } ipsec_reload() { echo "Reloading ipsec manual keys/policies." ${ipsec_program} -f "$ipsec_file" } load_rc_config $name run_rc_command "$1" Index: head/etc/rc.d/mountcritlocal =================================================================== --- head/etc/rc.d/mountcritlocal (revision 169667) +++ head/etc/rc.d/mountcritlocal (revision 169668) @@ -1,52 +1,52 @@ #!/bin/sh # # $NetBSD: mountcritlocal,v 1.7 2002/04/29 12:29:53 lukem Exp $ # $FreeBSD$ # # PROVIDE: mountcritlocal # REQUIRE: root # KEYWORD: nojail . /etc/rc.subr name="mountcritlocal" start_cmd="mountcritlocal_start" stop_cmd=":" mountcritlocal_start() { # Set up the list of network filesystem types for which mounting # should be delayed until after network initialization. case ${extra_netfs_types} in [Nn][Oo]) ;; *) netfs_types="${netfs_types} ${extra_netfs_types}" ;; esac # Mount everything except nfs filesystems. echo -n 'Mounting local file systems:' mount_excludes='no' for i in ${netfs_types}; do fstype=${i%:*} mount_excludes="${mount_excludes}${fstype}," done mount_excludes=${mount_excludes%,} mount -a -t ${mount_excludes} echo '.' case $? in 0) ;; *) echo 'Mounting /etc/fstab filesystems failed,' \ ' startup aborted' - kill -QUIT $$ + stop_boot true ;; esac } load_rc_config $name run_rc_command "$1" Index: head/etc/rc.d/mountlate =================================================================== --- head/etc/rc.d/mountlate (revision 169667) +++ head/etc/rc.d/mountlate (revision 169668) @@ -1,36 +1,36 @@ #!/bin/sh # # $FreeBSD$ # # PROVIDE: mountlate # REQUIRE: DAEMON # BEFORE: LOGIN # KEYWORD: nojail . /etc/rc.subr name="mountlate" start_cmd="mountlate_start" stop_cmd=":" mountlate_start() { # Mount "late" filesystems. echo -n 'Mounting late file systems:' mount -a -l echo '.' case $? in 0) ;; *) echo 'Mounting /etc/fstab filesystems failed,' \ ' startup aborted' - kill -QUIT $$ + stop_boot true ;; esac } load_rc_config $name run_rc_command "$1" Index: head/etc/rc.d/root =================================================================== --- head/etc/rc.d/root (revision 169667) +++ head/etc/rc.d/root (revision 169668) @@ -1,43 +1,43 @@ #!/bin/sh # # $NetBSD: root,v 1.2 2000/05/13 08:45:09 lukem Exp $ # $FreeBSD$ # # PROVIDE: root # REQUIRE: fsck # KEYWORD: nojail . /etc/rc.subr name="root" start_cmd="root_start" stop_cmd=":" root_start() { # root normally must be read/write, but if this is a BOOTP NFS # diskless boot it does not have to be. # case ${root_rw_mount} in [Nn][Oo] | '') ;; *) if ! mount -uw /; then echo 'Mounting root filesystem rw failed, startup aborted' - /bin/kill -QUIT $$ + stop_boot true fi ;; esac umount -a >/dev/null 2>&1 # If we booted a special kernel remove the record # so we will boot the default kernel next time. if [ -x /sbin/nextboot ]; then /sbin/nextboot -D fi } load_rc_config $name run_rc_command "$1" Index: head/etc/rc.subr =================================================================== --- head/etc/rc.subr (revision 169667) +++ head/etc/rc.subr (revision 169668) @@ -1,1549 +1,1571 @@ # $NetBSD: rc.subr,v 1.67 2006/10/07 11:25:15 elad Exp $ # $FreeBSD$ # # Copyright (c) 1997-2004 The NetBSD Foundation, Inc. # All rights reserved. # # This code is derived from software contributed to The NetBSD Foundation # by Luke Mewburn. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. All advertising materials mentioning features or use of this software # must display the following acknowledgement: # This product includes software developed by the NetBSD # Foundation, Inc. and its contributors. # 4. Neither the name of The NetBSD Foundation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # # rc.subr # functions used by various rc scripts # : ${rcvar_manpage:='rc.conf(5)'} +: ${RC_PID:=$$}; export RC_PID # # Operating System dependent/independent variables # if [ -z "${_rc_subr_loaded}" ]; then _rc_subr_loaded="YES" SYSCTL="/sbin/sysctl" SYSCTL_N="${SYSCTL} -n" CMD_OSTYPE="${SYSCTL_N} kern.ostype" OSTYPE=`${CMD_OSTYPE}` ID="/usr/bin/id" IDCMD="if [ -x $ID ]; then $ID -un; fi" PS="/bin/ps -ww" JID=`$PS -p $$ -o jid=` case ${OSTYPE} in FreeBSD) SYSCTL_W="${SYSCTL}" ;; NetBSD) SYSCTL_W="${SYSCTL} -w" ;; esac # # functions # --------- # # set_rcvar base_var # Set the variable name enabling a specific service. # FreeBSD uses ${service}_enable, while NetBSD uses # just the name of the service. For example: # FreeBSD: sendmail_enable="YES" # NetBSD : sendmail="YES" # $1 - if $name is not the base to work of off, specify # a different one # set_rcvar() { if [ -z "$1" ]; then base_var=${name} else base_var="$1" fi case ${OSTYPE} in FreeBSD) echo ${base_var}_enable ;; NetBSD) echo ${base_var} ;; *) echo 'XXX' ;; esac } # # force_depend script # Force a service to start. Intended for use by services # to resolve dependency issues. It is assumed the caller # has check to make sure this call is necessary # $1 - filename of script, in /etc/rc.d, to run # force_depend() { _depend="$1" info "${name} depends on ${_depend}, which will be forced to start." if ! /etc/rc.d/${_depend} forcestart; then warn "Unable to force ${_depend}. It may already be running." return 1 fi return 0 } # # checkyesno var # Test $1 variable, and warn if not set to YES or NO. # Return 0 if it's "yes" (et al), nonzero otherwise. # checkyesno() { eval _value=\$${1} debug "checkyesno: $1 is set to $_value." case $_value in # "yes", "true", "on", or "1" [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) return 0 ;; # "no", "false", "off", or "0" [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) return 1 ;; *) warn "\$${1} is not set properly - see ${rcvar_manpage}." return 1 ;; esac } # # reverse_list list # print the list in reverse order # reverse_list() { _revlist= for _revfile; do _revlist="$_revfile $_revlist" done echo $_revlist +} + +# stop_boot always +# If booting directly to multiuser or $always is enabled, +# send SIGTERM to the parent (/etc/rc) to abort the boot. +# Otherwise just exit. +# +stop_boot() +{ + local always + + if [ -n "$1" ] && checkyesno $1; then + always=true + else + always=false + fi + if [ "$autoboot" = yes -o "$always" = true ]; then + echo "ERROR: ABORTING BOOT (sending SIGTERM to parent)!" + kill -TERM ${RC_PID} + fi + exit 1 } # # mount_critical_filesystems type # Go through the list of critical filesystems as provided in # the rc.conf(5) variable $critical_filesystems_${type}, checking # each one to see if it is mounted, and if it is not, mounting it. # mount_critical_filesystems() { eval _fslist=\$critical_filesystems_${1} for _fs in $_fslist; do mount | ( _ismounted=false while read what _on on _type type; do if [ $on = $_fs ]; then _ismounted=true fi done if $_ismounted; then : else mount $_fs >/dev/null 2>&1 fi ) done } # # check_pidfile pidfile procname [interpreter] # Parses the first line of pidfile for a PID, and ensures # that the process is running and matches procname. # Prints the matching PID upon success, nothing otherwise. # interpreter is optional; see _find_processes() for details. # check_pidfile() { _pidfile=$1 _procname=$2 _interpreter=$3 if [ -z "$_pidfile" -o -z "$_procname" ]; then err 3 'USAGE: check_pidfile pidfile procname [interpreter]' fi if [ ! -f $_pidfile ]; then debug "pid file ($_pidfile): not readable." return fi read _pid _junk < $_pidfile if [ -z "$_pid" ]; then debug "pid file ($_pidfile): no pid in file." return fi _find_processes $_procname ${_interpreter:-.} '-p '"$_pid" } # # check_process procname [interpreter] # Ensures that a process (or processes) named procname is running. # Prints a list of matching PIDs. # interpreter is optional; see _find_processes() for details. # check_process() { _procname=$1 _interpreter=$2 if [ -z "$_procname" ]; then err 3 'USAGE: check_process procname [interpreter]' fi _find_processes $_procname ${_interpreter:-.} '-ax' } # # _find_processes procname interpreter psargs # Search for procname in the output of ps generated by psargs. # Prints the PIDs of any matching processes, space separated. # # If interpreter == ".", check the following variations of procname # against the first word of each command: # procname # `basename procname` # `basename procname` + ":" # "(" + `basename procname` + ")" # "[" + `basename procname` + "]" # # If interpreter != ".", read the first line of procname, remove the # leading #!, normalise whitespace, append procname, and attempt to # match that against each command, either as is, or with extra words # at the end. As an alternative, to deal with interpreted daemons # using perl, the basename of the interpreter plus a colon is also # tried as the prefix to procname. # _find_processes() { if [ $# -ne 3 ]; then err 3 'USAGE: _find_processes procname interpreter psargs' fi _procname=$1 _interpreter=$2 _psargs=$3 _pref= if [ $_interpreter != "." ]; then # an interpreted script # read interpreter name read _interp < ${_chroot}${_chroot:+"/"}$_procname _interp=${_interp#\#!} # strip #! set -- $_interp case $1 in */bin/env) shift # drop env to get real name ;; esac if [ $_interpreter != $1 ]; then warn "\$command_interpreter $_interpreter != $1" fi _interp="$* $_procname" # cleanup spaces, add _procname _interpbn=${1##*/} _fp_args='_argv' _fp_match='case "$_argv" in ${_interp}|"${_interp} "*|"${_interpbn}: ${_procname}"*)' else # a normal daemon _procnamebn=${_procname##*/} _fp_args='_arg0 _argv' _fp_match='case "$_arg0" in $_procname|$_procnamebn|${_procnamebn}:|"(${_procnamebn})"|"[${_procnamebn}]")' fi _proccheck="\ $PS 2>/dev/null -o pid= -o jid= -o command= $_psargs"' | while read _npid _jid '"$_fp_args"'; do '"$_fp_match"' if [ "$JID" -eq "$_jid" ]; then echo -n "$_pref$_npid"; _pref=" "; fi ;; esac done' # debug "in _find_processes: proccheck is ($_proccheck)." eval $_proccheck } # # wait_for_pids pid [pid ...] # spins until none of the pids exist # wait_for_pids() { _list="$@" if [ -z "$_list" ]; then return fi _prefix= while true; do _nlist=""; for _j in $_list; do if kill -0 $_j 2>/dev/null; then _nlist="${_nlist}${_nlist:+ }$_j" fi done if [ -z "$_nlist" ]; then break fi _list=$_nlist echo -n ${_prefix:-"Waiting for PIDS: "}$_list _prefix=", " sleep 2 done if [ -n "$_prefix" ]; then echo "." fi } # # run_rc_command argument # Search for argument in the list of supported commands, which is: # "start stop restart rcvar status poll ${extra_commands}" # If there's a match, run ${argument}_cmd or the default method # (see below). # # If argument has a given prefix, then change the operation as follows: # Prefix Operation # ------ --------- # fast Skip the pid check, and set rc_fast=yes # force Set ${rcvar} to YES, and set rc_force=yes # one Set ${rcvar} to YES # # The following globals are used: # # Name Needed Purpose # ---- ------ ------- # name y Name of script. # # command n Full path to command. # Not needed if ${rc_arg}_cmd is set for # each keyword. # # command_args n Optional args/shell directives for command. # # command_interpreter n If not empty, command is interpreted, so # call check_{pidfile,process}() appropriately. # # extra_commands n List of extra commands supported. # # pidfile n If set, use check_pidfile $pidfile $command, # otherwise use check_process $command. # In either case, only check if $command is set. # # procname n Process name to check for instead of $command. # # rcvar n This is checked with checkyesno to determine # if the action should be run. # # ${name}_program n Full path to command. # Meant to be used in /etc/rc.conf to override # ${command}. # # ${name}_chroot n Directory to chroot to before running ${command} # Requires /usr to be mounted. # # ${name}_chdir n Directory to cd to before running ${command} # (if not using ${name}_chroot). # # ${name}_flags n Arguments to call ${command} with. # NOTE: $flags from the parent environment # can be used to override this. # # ${name}_nice n Nice level to run ${command} at. # # ${name}_user n User to run ${command} as, using su(1) if not # using ${name}_chroot. # Requires /usr to be mounted. # # ${name}_group n Group to run chrooted ${command} as. # Requires /usr to be mounted. # # ${name}_groups n Comma separated list of supplementary groups # to run the chrooted ${command} with. # Requires /usr to be mounted. # # ${rc_arg}_cmd n If set, use this as the method when invoked; # Otherwise, use default command (see below) # # ${rc_arg}_precmd n If set, run just before performing the # ${rc_arg}_cmd method in the default # operation (i.e, after checking for required # bits and process (non)existence). # If this completes with a non-zero exit code, # don't run ${rc_arg}_cmd. # # ${rc_arg}_postcmd n If set, run just after performing the # ${rc_arg}_cmd method, if that method # returned a zero exit code. # # required_dirs n If set, check for the existence of the given # directories before running a (re)start command. # # required_files n If set, check for the readability of the given # files before running a (re)start command. # # required_modules n If set, ensure the given kernel modules are # loaded before running a (re)start command. # The check and possible loads are actually # done after start_precmd so that the modules # aren't loaded in vain, should the precmd # return a non-zero status to indicate a error. # If a word in the list looks like "foo:bar", # "foo" is the KLD file name and "bar" is the # module name. If a word looks like "foo~bar", # "foo" is the KLD file name and "bar" is a # egrep(1) pattern matching the module name. # Otherwise the module name is assumed to be # the same as the KLD file name, which is most # common. See load_kld(). # # required_vars n If set, perform checkyesno on each of the # listed variables before running the default # (re)start command. # # Default behaviour for a given argument, if no override method is # provided: # # Argument Default behaviour # -------- ----------------- # start if !running && checkyesno ${rcvar} # ${command} # # stop if ${pidfile} # rc_pid=$(check_pidfile $pidfile $command) # else # rc_pid=$(check_process $command) # kill $sig_stop $rc_pid # wait_for_pids $rc_pid # ($sig_stop defaults to TERM.) # # reload Similar to stop, except use $sig_reload instead, # and doesn't wait_for_pids. # $sig_reload defaults to HUP. # Note that `reload' isn't provided by default, # it should be enabled via $extra_commands. # # restart Run `stop' then `start'. # # status Show if ${command} is running, etc. # # poll Wait for ${command} to exit. # # rcvar Display what rc.conf variable is used (if any). # # Variables available to methods, and after run_rc_command() has # completed: # # Variable Purpose # -------- ------- # rc_arg Argument to command, after fast/force/one processing # performed # # rc_flags Flags to start the default command with. # Defaults to ${name}_flags, unless overridden # by $flags from the environment. # This variable may be changed by the precmd method. # # rc_pid PID of command (if appropriate) # # rc_fast Not empty if "fast" was provided (q.v.) # # rc_force Not empty if "force" was provided (q.v.) # # run_rc_command() { _return=0 rc_arg=$1 if [ -z "$name" ]; then err 3 'run_rc_command: $name is not set.' fi # Don't repeat the first argument when passing additional command- # line arguments to the command subroutines. # shift 1 rc_extra_args="$*" _rc_prefix= case "$rc_arg" in fast*) # "fast" prefix; don't check pid rc_arg=${rc_arg#fast} rc_fast=yes ;; force*) # "force prefix; always run rc_force=yes _rc_prefix=force rc_arg=${rc_arg#${_rc_prefix}} if [ -n "${rcvar}" ]; then eval ${rcvar}=YES fi ;; one*) # "one" prefix; set ${rcvar}=yes _rc_prefix=one rc_arg=${rc_arg#${_rc_prefix}} if [ -n "${rcvar}" ]; then eval ${rcvar}=YES fi ;; esac eval _override_command=\$${name}_program command=${command:+${_override_command:-$command}} _keywords="start stop restart rcvar $extra_commands" rc_pid= _pidcmd= _procname=${procname:-${command}} # setup pid check command if [ -n "$_procname" ]; then if [ -n "$pidfile" ]; then _pidcmd='rc_pid=$(check_pidfile '"$pidfile $_procname $command_interpreter"')' else _pidcmd='rc_pid=$(check_process '"$_procname $command_interpreter"')' fi if [ -n "$_pidcmd" ]; then _keywords="${_keywords} status poll" fi fi if [ -z "$rc_arg" ]; then rc_usage $_keywords fi if [ -n "$flags" ]; then # allow override from environment rc_flags=$flags else eval rc_flags=\$${name}_flags fi eval _chdir=\$${name}_chdir _chroot=\$${name}_chroot \ _nice=\$${name}_nice _user=\$${name}_user \ _group=\$${name}_group _groups=\$${name}_groups if [ -n "$_user" ]; then # unset $_user if running as that user if [ "$_user" = "$(eval $IDCMD)" ]; then unset _user fi fi # if ${rcvar} is set, and $1 is not # "rcvar", then run # checkyesno ${rcvar} # and return if that failed # if [ -n "${rcvar}" -a "$rc_arg" != "rcvar" ]; then if ! checkyesno ${rcvar}; then return 0 fi fi eval $_pidcmd # determine the pid if necessary for _elem in $_keywords; do if [ "$_elem" != "$rc_arg" ]; then continue fi # if there's a custom ${XXX_cmd}, # run that instead of the default # eval _cmd=\$${rc_arg}_cmd \ _precmd=\$${rc_arg}_precmd \ _postcmd=\$${rc_arg}_postcmd if [ -n "$_cmd" ]; then _run_rc_precmd || return 1 _run_rc_doit "$_cmd $rc_extra_args" || return 1 _run_rc_postcmd return $_return fi case "$rc_arg" in # default operations... status) _run_rc_precmd || return 1 if [ -n "$rc_pid" ]; then echo "${name} is running as pid $rc_pid." else echo "${name} is not running." return 1 fi _run_rc_postcmd ;; start) if [ -z "$rc_fast" -a -n "$rc_pid" ]; then echo 1>&2 "${name} already running? (pid=$rc_pid)." return 1 fi if [ ! -x ${_chroot}${_chroot:+"/"}${command} ]; then warn "run_rc_command: cannot run $command" return 1 fi _run_rc_precmd || return 1 # setup the full command to run # echo "Starting ${name}." if [ -n "$_chroot" ]; then _doit="\ ${_nice:+nice -n $_nice }\ chroot ${_user:+-u $_user }${_group:+-g $_group }${_groups:+-G $_groups }\ $_chroot $command $rc_flags $command_args" else _doit="\ ${_chdir:+cd $_chdir && }\ $command $rc_flags $command_args" if [ -n "$_user" ]; then _doit="su -m $_user -c 'sh -c \"$_doit\"'" fi if [ -n "$_nice" ]; then if [ -z "$_user" ]; then _doit="sh -c \"$_doit\"" fi _doit="nice -n $_nice $_doit" fi fi # run the full command # _run_rc_doit "$_doit" || return 1 # finally, run postcmd # _run_rc_postcmd ;; stop) if [ -z "$rc_pid" ]; then [ -n "$rc_fast" ] && return 0 _run_rc_notrunning return 1 fi _run_rc_precmd || return 1 # send the signal to stop # echo "Stopping ${name}." _doit=$(_run_rc_killcmd "${sig_stop:-TERM}") _run_rc_doit "$_doit" || return 1 # wait for the command to exit, # and run postcmd. wait_for_pids $rc_pid _run_rc_postcmd ;; reload) if [ -z "$rc_pid" ]; then _run_rc_notrunning return 1 fi _run_rc_precmd || return 1 _doit=$(_run_rc_killcmd "${sig_reload:-HUP}") _run_rc_doit "$_doit" || return 1 _run_rc_postcmd ;; restart) # prevent restart being called more # than once by any given script # if ${_rc_restart_done:-false}; then return 0 fi _rc_restart_done=true _run_rc_precmd || return 1 # run those in a subshell to keep global variables ( run_rc_command ${_rc_prefix}stop $rc_extra_args ) ( run_rc_command ${_rc_prefix}start $rc_extra_args ) _return=$? [ $_return -ne 0 ] && [ -z "$rc_force" ] && return 1 _run_rc_postcmd ;; poll) _run_rc_precmd || return 1 if [ -n "$rc_pid" ]; then wait_for_pids $rc_pid fi _run_rc_postcmd ;; rcvar) echo "# $name" if [ -n "$rcvar" ]; then if checkyesno ${rcvar}; then echo "${rcvar}=YES" else echo "${rcvar}=NO" fi fi ;; *) rc_usage $_keywords ;; esac return $_return done echo 1>&2 "$0: unknown directive '$rc_arg'." rc_usage $_keywords # not reached } # # Helper functions for run_rc_command: common code. # They use such global variables besides the exported rc_* ones: # # name R/W # ------------------ # _precmd R # _postcmd R # _return W # _run_rc_precmd() { check_required_before "$rc_arg" || return 1 if [ -n "$_precmd" ]; then debug "run_rc_command: ${rc_arg}_precmd: $_precmd $rc_extra_args" eval "$_precmd $rc_extra_args" _return=$? # If precmd failed and force isn't set, request exit. if [ $_return -ne 0 ] && [ -z "$rc_force" ]; then return 1 fi fi check_required_after "$rc_arg" || return 1 return 0 } _run_rc_postcmd() { if [ -n "$_postcmd" ]; then debug "run_rc_command: ${rc_arg}_postcmd: $_postcmd $rc_extra_args" eval "$_postcmd $rc_extra_args" _return=$? fi return 0 } _run_rc_doit() { debug "run_rc_command: doit: $*" eval "$@" _return=$? # If command failed and force isn't set, request exit. if [ $_return -ne 0 ] && [ -z "$rc_force" ]; then return 1 fi return 0 } _run_rc_notrunning() { local _pidmsg if [ -n "$pidfile" ]; then _pidmsg=" (check $pidfile)." else _pidmsg= fi echo 1>&2 "${name} not running?${_pidmsg}" } _run_rc_killcmd() { local _cmd _cmd="kill -$1 $rc_pid" if [ -n "$_user" ]; then _cmd="su -m ${_user} -c 'sh -c \"${_cmd}\"'" fi echo "$_cmd" } # # run_rc_script file arg # Start the script `file' with `arg', and correctly handle the # return value from the script. If `file' ends with `.sh', it's # sourced into the current environment. If `file' appears to be # a backup or scratch file, ignore it. Otherwise if it's # executable run as a child process. # run_rc_script() { _file=$1 _arg=$2 if [ -z "$_file" -o -z "$_arg" ]; then err 3 'USAGE: run_rc_script file arg' fi unset name command command_args command_interpreter \ extra_commands pidfile procname \ rcvar required_dirs required_files required_vars eval unset ${_arg}_cmd ${_arg}_precmd ${_arg}_postcmd case "$_file" in /etc/rc.d/*.sh) # run in current shell set $_arg; . $_file ;; *[~#]|*.OLD|*.bak|*.orig|*,v) # scratch file; skip warn "Ignoring scratch file $_file" ;; *) # run in subshell if [ -x $_file ]; then if [ -n "$rc_fast_and_loose" ]; then set $_arg; . $_file else ( trap "echo Script $_file interrupted; kill -QUIT $$" 3 trap "echo Script $_file interrupted; exit 1" 2 set $_arg; . $_file ) fi fi ;; esac } # # load_rc_config name # Source in the configuration file for a given name. # load_rc_config() { _name=$1 if [ -z "$_name" ]; then err 3 'USAGE: load_rc_config name' fi if ${_rc_conf_loaded:-false}; then : else if [ -r /etc/defaults/rc.conf ]; then debug "Sourcing /etc/defaults/rc.conf" . /etc/defaults/rc.conf source_rc_confs elif [ -r /etc/rc.conf ]; then debug "Sourcing /etc/rc.conf (/etc/defaults/rc.conf doesn't exist)." . /etc/rc.conf fi _rc_conf_loaded=true fi if [ -f /etc/rc.conf.d/"$_name" ]; then debug "Sourcing /etc/rc.conf.d/${_name}" . /etc/rc.conf.d/"$_name" fi # XXX - Deprecated variable name support # case ${OSTYPE} in FreeBSD) [ -n "$portmap_enable" ] && rpcbind_enable="$portmap_enable" [ -n "$portmap_program" ] && rpcbind_program="$portmap_program" [ -n "$portmap_flags" ] && rpcbind_flags="$portmap_flags" [ -n "$single_mountd_enable" ] && mountd_enable="$single_mountd_enable" [ -n "$xntpd_enable" ] && ntpd_enable="$xntpd_enable" [ -n "$xntpd_program" ] && ntpd_program="$xntpd_program" [ -n "$xntpd_flags" ] && ntpd_flags="$xntpd_flags" [ -n "$dhcp_program" ] && dhclient_program="$dhcp_program" [ -n "$dhcp_flags" ] && dhclient_flags="$dhcp_flags" ;; esac } # # load_rc_config_var name var # Read the rc.conf(5) var for name and set in the # current shell, using load_rc_config in a subshell to prevent # unwanted side effects from other variable assignments. # load_rc_config_var() { if [ $# -ne 2 ]; then err 3 'USAGE: load_rc_config_var name var' fi eval $(eval '( load_rc_config '$1' >/dev/null; if [ -n "${'$2'}" -o "${'$2'-UNSET}" != "UNSET" ]; then echo '$2'=\'\''${'$2'}\'\''; fi )' ) } # # rc_usage commands # Print a usage string for $0, with `commands' being a list of # valid commands. # rc_usage() { echo -n 1>&2 "Usage: $0 [fast|force|one](" _sep= for _elem; do echo -n 1>&2 "$_sep$_elem" _sep="|" done echo 1>&2 ")" exit 1 } # # err exitval message # Display message to stderr and log to the syslog, and exit with exitval. # err() { exitval=$1 shift if [ -x /usr/bin/logger ]; then logger "$0: ERROR: $*" fi echo 1>&2 "$0: ERROR: $*" exit $exitval } # # warn message # Display message to stderr and log to the syslog. # warn() { if [ -x /usr/bin/logger ]; then logger "$0: WARNING: $*" fi echo 1>&2 "$0: WARNING: $*" } # # info message # Display informational message to stdout and log to syslog. # info() { case ${rc_info} in [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) if [ -x /usr/bin/logger ]; then logger "$0: INFO: $*" fi echo "$0: INFO: $*" ;; esac } # # debug message # If debugging is enabled in rc.conf output message to stderr. # BEWARE that you don't call any subroutine that itself calls this # function. # debug() { case ${rc_debug} in [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) if [ -x /usr/bin/logger ]; then logger "$0: DEBUG: $*" fi echo 1>&2 "$0: DEBUG: $*" ;; esac } # # backup_file action file cur backup # Make a backup copy of `file' into `cur', and save the previous # version of `cur' as `backup' or use rcs for archiving. # # This routine checks the value of the backup_uses_rcs variable, # which can be either YES or NO. # # The `action' keyword can be one of the following: # # add `file' is now being backed up (and is possibly # being reentered into the backups system). `cur' # is created and RCS files, if necessary, are # created as well. # # update `file' has changed and needs to be backed up. # If `cur' exists, it is copied to to `back' or # checked into RCS (if the repository file is old), # and then `file' is copied to `cur'. Another RCS # check in done here if RCS is being used. # # remove `file' is no longer being tracked by the backups # system. If RCS is not being used, `cur' is moved # to `back', otherwise an empty file is checked in, # and then `cur' is removed. # # backup_file() { _action=$1 _file=$2 _cur=$3 _back=$4 if checkyesno backup_uses_rcs; then _msg0="backup archive" _msg1="update" # ensure that history file is not locked if [ -f $_cur,v ]; then rcs -q -u -U -M $_cur fi # ensure after switching to rcs that the # current backup is not lost if [ -f $_cur ]; then # no archive, or current newer than archive if [ ! -f $_cur,v -o $_cur -nt $_cur,v ]; then ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur rcs -q -kb -U $_cur co -q -f -u $_cur fi fi case $_action in add|update) cp -p $_file $_cur ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur rcs -q -kb -U $_cur co -q -f -u $_cur chown root:wheel $_cur $_cur,v ;; remove) cp /dev/null $_cur ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur rcs -q -kb -U $_cur chown root:wheel $_cur $_cur,v rm $_cur ;; esac else case $_action in add|update) if [ -f $_cur ]; then cp -p $_cur $_back fi cp -p $_file $_cur chown root:wheel $_cur ;; remove) mv -f $_cur $_back ;; esac fi } # make_symlink src link # Make a symbolic link 'link' to src from basedir. If the # directory in which link is to be created does not exist # a warning will be displayed and an error will be returned. # Returns 0 on sucess, 1 otherwise. # make_symlink() { local src link linkdir _me src="$1" link="$2" linkdir="`dirname $link`" _me="make_symlink()" if [ -z "$src" -o -z "$link" ]; then warn "$_me: requires two arguments." return 1 fi if [ ! -d "$linkdir" ]; then warn "$_me: the directory $linkdir does not exist." return 1 fi if ! ln -sf $src $link; then warn "$_me: unable to make a symbolic link from $link to $src" return 1 fi return 0 } # devfs_rulesets_from_file file # Reads a set of devfs commands from file, and creates # the specified rulesets with their rules. Returns non-zero # if there was an error. # devfs_rulesets_from_file() { local file _err _me file="$1" _me="devfs_rulesets_from_file" _err=0 if [ -z "$file" ]; then warn "$_me: you must specify a file" return 1 fi if [ ! -e "$file" ]; then debug "$_me: no such file ($file)" return 0 fi debug "reading rulesets from file ($file)" { while read line do case $line in \#*) continue ;; \[*\]*) rulenum=`expr "$line" : "\[.*=\([0-9]*\)\]"` if [ -z "$rulenum" ]; then warn "$_me: cannot extract rule number ($line)" _err=1 break fi rulename=`expr "$line" : "\[\(.*\)=[0-9]*\]"` if [ -z "$rulename" ]; then warn "$_me: cannot extract rule name ($line)" _err=1 break; fi eval $rulename=\$rulenum debug "found ruleset: $rulename=$rulenum" if ! /sbin/devfs rule -s $rulenum delset; then _err=1 break fi ;; *) rulecmd="${line%%"\#*"}" # evaluate the command incase it includes # other rules if [ -n "$rulecmd" ]; then debug "adding rule ($rulecmd)" if ! eval /sbin/devfs rule -s $rulenum $rulecmd then _err=1 break fi fi ;; esac if [ $_err -ne 0 ]; then debug "error in $_me" break fi done } < $file return $_err } # devfs_init_rulesets # Initializes rulesets from configuration files. Returns # non-zero if there was an error. # devfs_init_rulesets() { local file _me _me="devfs_init_rulesets" # Go through this only once if [ -n "$devfs_rulesets_init" ]; then debug "$_me: devfs rulesets already initialized" return fi for file in $devfs_rulesets; do devfs_rulesets_from_file $file || return 1 done devfs_rulesets_init=1 debug "$_me: devfs rulesets initialized" return 0 } # devfs_set_ruleset ruleset [dir] # Sets the default ruleset of dir to ruleset. The ruleset argument # must be a ruleset name as specified in devfs.rules(5) file. # Returns non-zero if it could not set it successfully. # devfs_set_ruleset() { local devdir rs _me [ -n "$1" ] && eval rs=\$$1 || rs= [ -n "$2" ] && devdir="-m "$2"" || devdir= _me="devfs_set_ruleset" if [ -z "$rs" ]; then warn "$_me: you must specify a ruleset number" return 1 fi debug "$_me: setting ruleset ($rs) on mount-point (${devdir#-m })" if ! /sbin/devfs $devdir ruleset $rs; then warn "$_me: unable to set ruleset $rs to ${devdir#-m }" return 1 fi return 0 } # devfs_apply_ruleset ruleset [dir] # Apply ruleset number $ruleset to the devfs mountpoint $dir. # The ruleset argument must be a ruleset name as specified # in a devfs.rules(5) file. Returns 0 on success or non-zero # if it could not apply the ruleset. # devfs_apply_ruleset() { local devdir rs _me [ -n "$1" ] && eval rs=\$$1 || rs= [ -n "$2" ] && devdir="-m "$2"" || devdir= _me="devfs_apply_ruleset" if [ -z "$rs" ]; then warn "$_me: you must specify a ruleset" return 1 fi debug "$_me: applying ruleset ($rs) to mount-point (${devdir#-m })" if ! /sbin/devfs $devdir rule -s $rs applyset; then warn "$_me: unable to apply ruleset $rs to ${devdir#-m }" return 1 fi return 0 } # devfs_domount dir [ruleset] # Mount devfs on dir. If ruleset is specified it is set # on the mount-point. It must also be a ruleset name as specified # in a devfs.rules(5) file. Returns 0 on success. # devfs_domount() { local devdir rs _me devdir="$1" [ -n "$2" ] && rs=$2 || rs= _me="devfs_domount()" if [ -z "$devdir" ]; then warn "$_me: you must specify a mount-point" return 1 fi debug "$_me: mount-point is ($devdir), ruleset is ($rs)" if ! mount -t devfs dev "$devdir"; then warn "$_me: Unable to mount devfs on $devdir" return 1 fi if [ -n "$rs" ]; then devfs_init_rulesets devfs_set_ruleset $rs $devdir devfs -m $devdir rule applyset fi return 0 } # devfs_mount_jail dir [ruleset] # Mounts a devfs file system appropriate for jails # on the directory dir. If ruleset is specified, the ruleset # it names will be used instead. If present, ruleset must # be the name of a ruleset as defined in a devfs.rules(5) file. # This function returns non-zero if an error occurs. # devfs_mount_jail() { local jdev rs _me jdev="$1" [ -n "$2" ] && rs=$2 || rs="devfsrules_jail" _me="devfs_mount_jail" devfs_init_rulesets if ! devfs_domount "$jdev" $rs; then warn "$_me: devfs was not mounted on $jdev" return 1 fi return 0 } # Provide a function for normalizing the mounting of memory # filesystems. This should allow the rest of the code here to remain # as close as possible between 5-current and 4-stable. # $1 = size # $2 = mount point # $3 = (optional) extra mdmfs flags mount_md() { if [ -n "$3" ]; then flags="$3" fi /sbin/mdmfs $flags -s $1 md $2 } # Code common to scripts that need to load a kernel module # if it isn't in the kernel yet. Syntax: # load_kld [-e regex] [-m module] file # where -e or -m chooses the way to check if the module # is already loaded: # regex is egrep'd in the output from `kldstat -v', # module is passed to `kldstat -m'. # The default way is as though `-m file' were specified. load_kld() { local _loaded _mod _opt _re while getopts "e:m:" _opt; do case "$_opt" in e) _re="$OPTARG" ;; m) _mod="$OPTARG" ;; *) err 3 'USAGE: load_kld [-e regex] [-m module] file' ;; esac done shift $(($OPTIND - 1)) if [ $# -ne 1 ]; then err 3 'USAGE: load_kld [-e regex] [-m module] file' fi _mod=${_mod:-$1} _loaded=false if [ -n "$_re" ]; then if kldstat -v | egrep -q -e "$_re"; then _loaded=true fi else if kldstat -q -m "$_mod"; then _loaded=true fi fi if ! $_loaded; then if ! kldload "$1"; then warn "Unable to load kernel module $1" return 1 else info "$1 kernel module loaded." fi else debug "load_kld: $1 kernel module already loaded." fi return 0 } # ltr str src dst # Change every $src in $str to $dst. # Useful when /usr is not yet mounted and we cannot use tr(1), sed(1) nor # awk(1). ltr() { local _str _src _dst _out _com _str=$1 _src=$2 _dst=$3 _out="" IFS=${_src} for _com in ${_str}; do if [ -z "${_out}" ]; then _out="${_com}" else _out="${_out}${_dst}${_com}" fi done echo "${_out}" } # Creates a list of providers for GELI encryption. geli_make_list() { local devices devices2 local provider mountpoint type options rest # Create list of GELI providers from fstab. while read provider mountpoint type options rest ; do case ":${options}" in :*noauto*) noauto=yes ;; *) noauto=no ;; esac case ":${provider}" in :#*) continue ;; *.eli) # Skip swap devices. if [ "${type}" = "swap" -o "${options}" = "sw" -o "${noauto}" = "yes" ]; then continue fi devices="${devices} ${provider}" ;; esac done < /etc/fstab # Append providers from geli_devices. devices="${devices} ${geli_devices}" for provider in ${devices}; do provider=${provider%.eli} provider=${provider#/dev/} devices2="${devices2} ${provider}" done echo ${devices2} } # Find scripts in local_startup directories that use the old syntax # find_local_scripts_old () { zlist='' slist='' for dir in ${local_startup}; do if [ -d "${dir}" ]; then for file in ${dir}/[0-9]*.sh; do grep '^# PROVIDE:' $file >/dev/null 2>&1 && continue zlist="$zlist $file" done for file in ${dir}/[^0-9]*.sh; do grep '^# PROVIDE:' $file >/dev/null 2>&1 && continue slist="$slist $file" done fi done } find_local_scripts_new () { local_rc='' for dir in ${local_startup}; do if [ -d "${dir}" ]; then for file in `grep -l '^# PROVIDE:' ${dir}/* 2>/dev/null`; do case "$file" in *.sample) ;; *) if [ -x "$file" ]; then local_rc="${local_rc} ${file}" fi ;; esac done fi done } # check_required_{before|after} command # Check for things required by the command before and after its precmd, # respectively. The two separate functions are needed because some # conditions should prevent precmd from being run while other things # depend on precmd having already been run. # check_required_before() { local _f case "$1" in start) for _f in $required_vars; do if ! checkyesno $_f; then warn "\$${_f} is not enabled." if [ -z "$rc_force" ]; then return 1 fi fi done for _f in $required_dirs; do if [ ! -d "${_f}/." ]; then warn "${_f} is not a directory." if [ -z "$rc_force" ]; then return 1 fi fi done for _f in $required_files; do if [ ! -r "${_f}" ]; then warn "${_f} is not readable." if [ -z "$rc_force" ]; then return 1 fi fi done ;; esac return 0 } check_required_after() { local _f _args case "$1" in start) for _f in $required_modules; do case "${_f}" in *~*) _args="-e ${_f#*~} ${_f%%~*}" ;; *:*) _args="-m ${_f#*:} ${_f%%:*}" ;; *) _args="${_f}" ;; esac if ! load_kld ${_args}; then if [ -z "$rc_force" ]; then return 1 fi fi done ;; esac return 0 } fi _rc_subr_loaded=: Index: head/share/man/man8/rc.8 =================================================================== --- head/share/man/man8/rc.8 (revision 169667) +++ head/share/man/man8/rc.8 (revision 169668) @@ -1,563 +1,558 @@ .\" Copyright (c) 1980, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" Portions of this manual page are Copyrighted by .\" The NetBSD Foundation. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)rc.8 8.2 (Berkeley) 12/11/93 .\" $FreeBSD$ .\" -.Dd December 19, 2005 +.Dd May 18, 2007 .Dt RC 8 .Os .Sh NAME .Nm rc .Nd command scripts for auto-reboot and daemon startup .Sh SYNOPSIS .Nm .Nm rc.conf .Nm rc.conf.local .Nm rc.d/ .Nm rc.firewall .Nm rc.local .Nm rc.shutdown .Nm rc.subr .Sh DESCRIPTION The .Nm utility is the command script which controls the automatic boot process after being called by .Xr init 8 . The .Nm rc.local script contains commands which are pertinent only to a specific site. Typically, the .Pa /usr/local/etc/rc.d/ mechanism is used instead of .Nm rc.local these days but if you want to use .Nm rc.local , it is still supported. In this case, it should source .Pa /etc/rc.conf and contain additional custom startup code for your system. The best way to handle .Nm rc.local , however, is to separate it out into .Nm rc.d/ style scripts and place them under .Pa /usr/local/etc/rc.d/ . The .Nm rc.conf file contains the global system configuration information referenced by the startup scripts, while .Nm rc.conf.local contains the local system configuration. See .Xr rc.conf 5 for more information. .Pp The .Nm rc.d/ directories contain scripts which will be automatically executed at boot time and shutdown time. .Ss Operation of Nm .Bl -enum .It If autobooting, set .Va autoboot Ns = Ns Li yes and enable a flag .Pq Va rc_fast Ns = Ns Li yes , which prevents the .Nm rc.d/ scripts from performing the check for already running processes (thus speeding up the boot process). This .Va rc_fast Ns = Ns Li yes speedup will not occur when .Nm is started up after exiting the single-user shell. .It Determine whether the system is booting diskless, and if so run the .Pa /etc/rc.initdiskless script. .It Source .Pa /etc/rc.subr to load various .Xr rc.subr 8 shell functions to use. .It Load the configuration files. .It Determine if booting in a jail, and add .Dq Li nojail to the list of KEYWORDS to skip in .Xr rcorder 8 . .It Invoke .Xr rcorder 8 to order the files in .Pa /etc/rc.d/ that do not have a .Dq Li nostart KEYWORD (refer to .Xr rcorder 8 Ns 's .Fl s flag). .It Call each script in turn using .Fn run_rc_script (from .Xr rc.subr 8 ) , which sets .Va $1 to .Dq Li start , and sources the script in a subshell. If the script has a .Pa .sh suffix then it is sourced directly into the current shell. Stop processing when the script that is the value of the .Va $early_late_divider has been run. .It Re-run .Xr rcorder 8 , this time including the scripts in the .Va $local_startup directories. Ignore everything up to the .Va $early_late_divider , then start executing the scripts as described above. .El .Ss Operation of Nm rc.shutdown .Bl -enum .It Source .Pa /etc/rc.subr to load various .Xr rc.subr 8 shell functions to use. .It Load the configuration files. .It Invoke .Xr rcorder 8 to order the files in .Pa /etc/rc.d/ and the .Va $local_startup directories that have a .Dq Li shutdown KEYWORD (refer to .Xr rcorder 8 Ns 's .Fl k flag), reverse that order, and assign the result to a variable. .It Call each script in turn using .Fn run_rc_script (from .Xr rc.subr 8 ) , which sets .Va $1 to .Dq Li stop , and sources the script in a subshell. If the script has a .Pa .sh suffix then it is sourced directly into the current shell. .El .Ss Contents of Nm rc.d/ .Nm rc.d/ is located in .Pa /etc/rc.d/ . The following file naming conventions are currently used in .Nm rc.d/ : .Bl -tag -width ".Pa ALLUPPERCASE" -offset indent .It Pa ALLUPPERCASE Scripts that are .Dq placeholders to ensure that certain operations are performed before others. In order of startup, these are: .Bl -tag -width ".Pa NETWORKING" .It Pa NETWORKING Ensure basic network services are running, including general network configuration. .It Pa SERVERS Ensure basic services exist for services that start early (such as .Pa named ) , because they are required by .Pa DAEMON below. .It Pa DAEMON Check-point before all general purpose daemons such as .Pa lpd and .Pa ntpd . .It Pa LOGIN Check-point before user login services .Pa ( inetd and .Pa sshd ) , as well as services which might run commands as users .Pa ( cron and .Pa sendmail ) . .El .It Pa foo.sh Scripts that are to be sourced into the current shell rather than a subshell have a .Pa .sh suffix. Extreme care must be taken in using this, as the startup sequence will terminate if the script does. .It Pa bar Scripts that are sourced in a subshell. -These can stop the boot if necessary with the following shell -commands: -.Bd -literal -offset indent -if [ "$autoboot" = yes ]; then - kill -TERM $$ -fi -exit 1 -.Ed -.Pp -Note that this should be used extremely sparingly! +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 +.Fn stop_boot +function (from +.Xr rc.subr 8 ). .El .Pp Each script should contain .Xr rcorder 8 keywords, especially an appropriate .Dq Li PROVIDE entry, and if necessary .Dq Li REQUIRE and .Dq Li BEFORE keywords. .Pp Each script is expected to support at least the following arguments, which are automatically supported if it uses the .Fn run_rc_command function: .Bl -tag -width ".Cm restart" -offset indent .It Cm start Start the service. This should check that the service is to be started as specified by .Xr 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 .Fx scripts if the system is starting directly to multi-user mode, to speed up the boot process. If .Cm forcestart is given, ignore the .Xr rc.conf 5 check and start anyway. .It Cm stop If the service is to be started as specified by .Xr rc.conf 5 , stop the service. This should check that the service is running and complain if it is not. If .Cm forcestop is given, ignore the .Xr rc.conf 5 check and attempt to stop. .It Cm restart Perform a .Cm stop then a .Cm start . .It Cm status If the script starts a process (rather than performing a one-off operation), show the status of the process. Otherwise it is not necessary to support this argument. Defaults to displaying the process ID of the program (if running). .It Cm poll If the script starts a process (rather than performing a one-off operation), wait for the command to exit. Otherwise it is not necessary to support this argument. .It Cm rcvar Display which .Xr rc.conf 5 variables are used to control the startup of the service (if any). .El .Pp If a script must implement additional commands it can list them in the .Va extra_commands variable, and define their actions in a variable constructed from the command name (see the .Sx EXAMPLES section). .Pp The following key points apply to old-style scripts in .Pa /usr/local/etc/rc.d/ : .Pp .Bl -bullet .It Scripts are only executed if their .Xr basename 1 matches the shell globbing pattern .Pa *.sh , and they are executable. Any other files or directories present within the directory are silently ignored. .It When a script is executed at boot time, it is passed the string .Dq Li start as its first and only argument. At shutdown time, it is passed the string .Dq Li stop as its first and only argument. All .Nm rc.d/ scripts are expected to handle these arguments appropriately. If no action needs to be taken at a given time (either boot time or shutdown time), the script should exit successfully and without producing an error message. .It The scripts within each directory are executed in lexicographical order. If a specific order is required, numbers may be used as a prefix to the existing filenames, so for example .Pa 100.foo would be executed before .Pa 200.bar ; without the numeric prefixes the opposite would be true. .It The output from each script is traditionally a space character, followed by the name of the software package being started or shut down, .Em without a trailing newline character (see the .Sx EXAMPLES section). .El .Sh SCRIPTS OF INTEREST When an automatic reboot is in progress, .Nm is invoked with the argument .Cm autoboot . One of the scripts run from .Pa /etc/rc.d/ is .Pa /etc/rc.d/fsck . This script runs .Xr fsck 8 with option .Fl p and .Fl F to .Dq preen all the disks of minor inconsistencies resulting from the last system shutdown. If this fails, then checks/repairs of serious inconsistencies caused by hardware or software failure will be performed in the background at the end of the booting process. If .Cm autoboot is not set, when going from single-user to multi-user mode for example, the script does not do anything. .Pp The .Nm rc.early script is run very early in the startup process, immediately before the file system check. The .Nm rc.early script is deprecated. Any commands in this file should be separated out into .Nm rc.d/ style scripts and integrated into the .Nm system. .Pp The .Pa /etc/rc.d/local script can execute scripts from multiple .Nm rc.d/ directories. The default locations are .Pa /usr/local/etc/rc.d/ and .Pa /usr/X11R6/etc/rc.d/ , but these may be overridden with the .Va local_startup .Xr rc.conf 5 variable. .Pp The .Pa /etc/rc.d/serial script is used to set any special configurations for serial devices. .Pp The .Nm rc.firewall script is used to configure rules for the kernel based firewall service. It has several possible options: .Pp .Bl -tag -width ".Ar filename" -compact -offset indent .It Cm open will allow anyone in .It Cm client will try to protect just this machine .It Cm simple will try to protect a whole network .It Cm closed totally disables IP services except via .Pa lo0 interface .It Cm UNKNOWN disables the loading of firewall rules .It Ar filename will load the rules in the given filename (full path required). .El .Pp The .Pa /etc/rc.d/atm* scripts are used to configure ATM network interfaces. The interfaces are configured in three passes. The first pass performs the initial interface configuration. The second pass completes the interface configuration and defines PVCs and permanent ATMARP entries. The third pass starts any ATM daemons. .Pp Most daemons, including network related daemons, have their own script in .Pa /etc/rc.d/ , which can be used to start, stop, and check the status of the service. .Pp Any architecture specific scripts, such as .Pa /etc/rc.d/apm for example, specifically check that they are on that architecture before starting the daemon. .Pp Following tradition, all startup files reside in .Pa /etc . .Sh FILES .Bl -tag -compact .It Pa /etc/rc .It Pa /etc/rc.conf .It Pa /etc/rc.conf.local .It Pa /etc/rc.d/ .It Pa /etc/rc.firewall .It Pa /etc/rc.local .It Pa /etc/rc.shutdown .It Pa /etc/rc.subr .It Pa /var/run/dmesg.boot .Xr dmesg 8 results soon after the .Nm process begins. Useful when .Xr dmesg 8 buffer in the kernel no longer has this information. .El .Sh EXAMPLES The following is a minimal .Nm rc.d/ style script. Most scripts require little more than the following. .Bd -literal -offset indent #!/bin/sh # # PROVIDE: foo # REQUIRE: bar_service_required_to_precede_foo \&. /etc/rc.subr name="foo" rcvar=`set_rcvar` command="/usr/local/bin/foo" load_rc_config $name run_rc_command "$1" .Ed .Pp Certain scripts may want to provide enhanced functionality. The user may access this functionality through additional commands. The script may list and define as many commands at it needs. .Bd -literal -offset indent #!/bin/sh # # PROVIDE: foo # REQUIRE: bar_service_required_to_precede_foo # BEFORE: baz_service_requiring_foo_to_precede_it \&. /etc/rc.subr name="foo" rcvar=`set_rcvar` command="/usr/local/bin/foo" extra_commands="nop hello" hello_cmd="echo Hello World." nop_cmd="do_nop" do_nop() { echo "I do nothing." } load_rc_config $name run_rc_command "$1" .Ed .Pp As all processes are killed by .Xr init 8 at shutdown, the explicit .Xr kill 1 is unnecessary, but is often included. .Sh SEE ALSO .Xr kill 1 , .Xr rc.conf 5 , .Xr init 8 , .Xr rcorder 8 , .Xr rc.subr 8 , .Xr reboot 8 , .Xr savecore 8 .Sh HISTORY The .Nm utility appeared in .Bx 4.0 . Index: head/share/man/man8/rc.subr.8 =================================================================== --- head/share/man/man8/rc.subr.8 (revision 169667) +++ head/share/man/man8/rc.subr.8 (revision 169668) @@ -1,907 +1,924 @@ .\" $NetBSD: rc.subr.8,v 1.12 2004/01/06 00:52:24 lukem Exp $ .\" .\" Copyright (c) 2002-2004 The NetBSD Foundation, Inc. .\" All rights reserved. .\" .\" This code is derived from software contributed to The NetBSD Foundation .\" by Luke Mewburn. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the NetBSD .\" Foundation, Inc. and its contributors. .\" 4. Neither the name of The NetBSD Foundation nor the names of its .\" contributors may be used to endorse or promote products derived .\" from this software without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED .\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR .\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS .\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR .\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF .\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS .\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN .\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" .\" $FreeBSD$ .\" -.Dd December 27, 2006 +.Dd May 18, 2007 .Dt RC.SUBR 8 .Os .Sh NAME .Nm rc.subr .Nd functions used by system shell scripts .Sh SYNOPSIS .Bl -item -compact .It .Ic .\& Pa /etc/rc.subr .Pp .It .Ic backup_file Ar action Ar file Ar current Ar backup .It .Ic checkyesno Ar var .It .Ic check_pidfile Ar pidfile Ar procname Op Ar interpreter .It .Ic check_process Ar procname Op Ar interpreter .It .Ic debug Ar message .It .Ic err Ar exitval Ar message .It .Ic force_depend Ar name .It .Ic info Ar message .It .Ic load_kld Oo Fl e Ar regex Oc Oo Fl m Ar module Oc Ar file .It .Ic load_rc_config Ar name .It .Ic load_rc_config_var Ar name Ar var .It .Ic mount_critical_filesystems Ar type .It .Ic rc_usage Ar command ... .It .Ic reverse_list Ar item ... .It .Ic run_rc_command Ar argument .It .Ic run_rc_script Ar file Ar argument .It .Ic set_rcvar Op Ar base .It .Ic wait_for_pids Op Ar pid ... .It .Ic warn Ar message .El .Sh DESCRIPTION The .Nm script contains commonly used shell script functions and variable definitions which are used by various scripts such as .Xr rc 8 . Scripts required by ports in .Pa /usr/local/etc/rc.d will also eventually be rewritten to make use of it. .Pp The .Nm functions were mostly imported from .Nx and it is intended that they remain synced between the two projects. With that in mind there are several variable definitions that can help in this regard. They are: .Bl -tag -width 4n .It Va OSTYPE Its value will be either .Qq Li FreeBSD or .Qq Li NetBSD , depending on which OS it is running on. .It Va SYSCTL The path to the .Xr sysctl 8 command. .It Va SYSCTL_N The path and argument list to display only the .Xr sysctl 8 values instead of a .Ar name Ns = Ns Ar value pair. .It Va SYSCTL_W The path and argument to write or modify .Xr sysctl 8 values. .El .Pp The .Nm functions are accessed by sourcing .Pa /etc/rc.subr into the current shell. .Pp The following shell functions are available: .Bl -tag -width 4n .It Ic backup_file Ar action file current backup Make a backup copy of .Ar file into .Ar current . If the .Xr rc.conf 5 variable .Va backup_uses_rcs is .Dq Li YES , use .Xr rcs 1 to archive the previous version of .Ar current , otherwise save the previous version of .Ar current as .Ar backup . .Pp The .Ar action argument may be one of the following: .Bl -tag -width ".Cm remove" .It Cm add .Ar file is now being backed up by or possibly re-entered into this backup mechanism. .Ar current is created, and if necessary, the .Xr rcs 1 files are created as well. .It Cm update .Ar file has changed and needs to be backed up. If .Ar current exists, it is copied to .Ar backup or checked into .Xr rcs 1 (if the repository file is old), and then .Ar file is copied to .Ar current . .It Cm remove .Ar file is no longer being tracked by this backup mechanism. If .Xr rcs 1 is being used, an empty file is checked in and .Ar current is removed, otherwise .Ar current is moved to .Ar backup . .El .It Ic checkyesno Ar var Return 0 if .Ar var is defined to .Dq Li YES , .Dq Li TRUE , .Dq Li ON , or .Ql 1 . Return 1 if .Ar var is defined to .Dq Li NO , .Dq Li FALSE , .Dq Li OFF , or .Ql 0 . Otherwise, warn that .Ar var is not set correctly. The values are case insensitive. .It Ic check_pidfile Ar pidfile procname Op Ar interpreter Parses the first word of the first line of .Ar pidfile for a PID, and ensures that the process with that PID is running and its first argument matches .Ar procname . Prints the matching PID if successful, otherwise nothing. If .Ar interpreter is provided, parse the first line of .Ar procname , ensure that the line is of the form: .Pp .Dl "#! interpreter [...]" .Pp and use .Ar interpreter with its optional arguments and .Ar procname appended as the process string to search for. .It Ic check_process Ar procname Op Ar interpreter Prints the PIDs of any processes that are running with a first argument that matches .Ar procname . .Ar interpreter is handled as per .Ic check_pidfile . .It Ic debug Ar message Display a debugging message to .Va stderr , log it to the system log using .Xr logger 1 , and return to the caller. The error message consists of the script name (from .Va $0 ) , followed by .Dq Li ": DEBUG: " , and then .Ar message . This function is intended to be used by developers as an aid to debugging scripts. It can be turned on or off by the .Xr rc.conf 5 variable .Va rc_debug . .It Ic err Ar exitval message Display an error message to .Va stderr , log it to the system log using .Xr logger 1 , and .Ic exit with an exit value of .Ar exitval . The error message consists of the script name (from .Va $0 ) , followed by .Dq Li ": ERROR: " , and then .Ar message . .It Ic force_depend name Output an advisory message and force the .Ar name service to start. The .Ar name argument is the .Xr basename 1 component of the path to the script, usually .Pa /etc/rc.d/name . If the script fails for any reason it will output a warning and return with a return value of 1. If it was successful it will return 0. .It Ic info Ar message Display an informational message to .Va stdout , and log it to the system log using .Xr logger 1 . The message consists of the script name (from .Va $0 ) , followed by .Dq Li ": INFO: " , and then .Ar message . The display of this informational output can be turned on or off by the .Xr rc.conf 5 variable .Va rc_info . .It Ic load_kld Oo Fl e Ar regex Oc Oo Fl m Ar module Oc Ar file Load .Ar file as a kernel module unless it is already loaded. For the purpose of checking the module status, either the exact module name can be specified using .Fl m , or an .Xr egrep 1 regular expression matching the module name can be supplied via .Fl e . By default, the module is assumed to have the same name as .Ar file , which is not always the case. .It Ic load_rc_config Ar name Source in the configuration files for .Ar name . First, .Pa /etc/rc.conf is sourced if it has not yet been read in. Then, .Pa /etc/rc.conf.d/ Ns Ar name is sourced if it is an existing file. The latter may also contain other variable assignments to override .Ic run_rc_command arguments defined by the calling script, to provide an easy mechanism for an administrator to override the behaviour of a given .Xr rc.d 8 script without requiring the editing of that script. .It Ic load_rc_config_var Ar name Ar var Read the .Xr rc.conf 5 variable .Ar var for .Ar name and set in the current shell, using .Ic load_rc_config in a sub-shell to prevent unwanted side effects from other variable assignments. .It Ic mount_critical_filesystems Ar type Go through a list of critical file systems, as found in the .Xr rc.conf 5 variable .Va critical_filesystems_ Ns Ar type , mounting each one that is not currently mounted. .It Ic rc_usage Ar command ... Print a usage message for .Va $0 , with .Ar commands being the list of valid arguments prefixed by .Sm off .Dq Bq Li fast | force | one . .Sm on .It Ic reverse_list Ar item ... Print the list of .Ar items in reverse order. .It Ic run_rc_command Ar argument Run the .Ar argument method for the current .Xr rc.d 8 script, based on the settings of various shell variables. .Ic run_rc_command is extremely flexible, and allows fully functional .Xr rc.d 8 scripts to be implemented in a small amount of shell code. .Pp .Ar argument is searched for in the list of supported commands, which may be one of: .Bl -tag -width ".Cm restart" -offset indent .It Cm start Start the service. This should check that the service is to be started as specified by .Xr 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 .Fx scripts if the system is starting directly to multi-user mode, to speed up the boot process. .It Cm stop If the service is to be started as specified by .Xr rc.conf 5 , stop the service. This should check that the service is running and complain if it is not. .It Cm restart Perform a .Cm stop then a .Cm start . Defaults to displaying the process ID of the program (if running). .It Cm rcvar Display which .Xr rc.conf 5 variables are used to control the startup of the service (if any). .El .Pp If .Va pidfile or .Va procname is set, also support: .Bl -tag -width ".Cm restart" -offset indent .It Cm poll Wait for the command to exit. .It Cm status Show the status of the process. .El .Pp Other supported commands are listed in the optional variable .Va extra_commands . .Pp .Ar argument may have one of the following prefixes which alters its operation: .Bl -tag -width ".Li force" -offset indent .It Li fast Skip the check for an existing running process, and sets .Va rc_fast Ns = Ns Li YES . .It Li force Skip the checks for .Va rcvar being set to .Dq Li YES , and sets .Va rc_force Ns = Ns Li YES . This ignores .Ar argument Ns Va _precmd returning non-zero, and ignores any of the .Va required_* tests failing, and always returns a zero exit status. .It Li one Skip the checks for .Va rcvar being set to .Dq Li YES , but performs all the other prerequisite tests. .El .Pp .Ic run_rc_command uses the following shell variables to control its behaviour. Unless otherwise stated, these are optional. .Bl -tag -width ".Va procname" -offset indent .It Va name The name of this script. This is not optional. .It Va rcvar The value of .Va rcvar is checked with .Ic checkyesno to determine if this method should be run. .It Va command Full path to the command. Not required if .Ar argument Ns Va _cmd is defined for each supported keyword. Can be overridden by .Va ${name}_program . .It Va command_args Optional arguments and/or shell directives for .Va command . .It Va command_interpreter .Va command is started with: .Pp .Dl "#! command_interpreter [...]" .Pp which results in its .Xr ps 1 command being: .Pp .Dl "command_interpreter [...] command" .Pp so use that string to find the PID(s) of the running command rather than .Va command . .It Va extra_commands Extra commands/keywords/arguments supported. .It Va pidfile Path to PID file. Used to determine the PID(s) of the running command. If .Va pidfile is set, use: .Pp .Dl "check_pidfile $pidfile $procname" .Pp to find the PID. Otherwise, if .Va command is set, use: .Pp .Dl "check_process $procname" .Pp to find the PID. .It Va procname Process name to check for. Defaults to the value of .Va command . .It Va required_dirs Check for the existence of the listed directories before running the .Cm start method. .It Va required_files Check for the readability of the listed files before running the .Cm start method. .It Va required_modules Ensure that the listed kernel modules are loaded before running the .Cm start method. This is done after invoking the commands from .Va start_precmd so that the missing modules are not loaded in vain if the preliminary commands indicate a error condition. A word in the list can have an optional .Dq Li : Ns Ar modname or .Dq Li ~ Ns Ar pattern suffix. The .Ar modname or .Ar pattern parameter is passed to .Ic load_kld through a .Fl m or .Fl e option, respectively. See the description of .Ic load_kld in this document for details. .It Va required_vars Perform .Ic checkyesno on each of the list variables before running the .Cm start method. .It Va ${name}_chdir Directory to .Ic cd to before running .Va command , if .Va ${name}_chroot is not provided. .It Va ${name}_chroot Directory to .Xr chroot 8 to before running .Va command . Only supported after .Pa /usr is mounted. .It Va ${name}_flags Arguments to call .Va command with. This is usually set in .Xr rc.conf 5 , and not in the .Xr rc.d 8 script. The environment variable .Sq Ev flags can be used to override this. .It Va ${name}_nice .Xr nice 1 level to run .Va command as. Only supported after .Pa /usr is mounted. .It Va ${name}_program Full path to the command. Overrides .Va command if both are set, but has no effect if .Va command is unset. As a rule, .Va command should be set in the script while .Va ${name}_program should be set in .Xr rc.conf 5 . .It Va ${name}_user User to run .Va command as, using .Xr chroot 8 . if .Va ${name}_chroot is set, otherwise uses .Xr su 1 . Only supported after .Pa /usr is mounted. .It Va ${name}_group Group to run the chrooted .Va command as. .It Va ${name}_groups Comma separated list of supplementary groups to run the chrooted .Va command with. .It Ar argument Ns Va _cmd Shell commands which override the default method for .Ar argument . .It Ar argument Ns Va _precmd Shell commands to run just before running .Ar argument Ns Va _cmd or the default method for .Ar argument . If this returns a non-zero exit code, the main method is not performed. If the default method is being executed, this check is performed after the .Va required_* checks and process (non-)existence checks. .It Ar argument Ns Va _postcmd Shell commands to run if running .Ar argument Ns Va _cmd or the default method for .Ar argument returned a zero exit code. .It Va sig_stop Signal to send the processes to stop in the default .Cm stop method. Defaults to .Dv SIGTERM . .It Va sig_reload Signal to send the processes to reload in the default .Cm reload method. Defaults to .Dv SIGHUP . .El .Pp For a given method .Ar argument , if .Ar argument Ns Va _cmd is not defined, then a default method is provided by .Ic run_rc_command : .Bl -tag -width ".Sy Argument" -offset indent .It Sy Argument .Sy Default method .It Cm start If .Va command is not running and .Ic checkyesno Va rcvar succeeds, start .Va command . .It Cm stop Determine the PIDs of .Va command with .Ic check_pidfile or .Ic check_process (as appropriate), .Ic kill Va sig_stop those PIDs, and run .Ic wait_for_pids on those PIDs. .It Cm reload Similar to .Cm stop , except that it uses .Va sig_reload instead, and does not run .Ic wait_for_pids . Another difference from .Cm stop is that .Cm reload is not provided by default. It can be enabled via .Va extra_commands if appropriate: .Pp .Dl "extra_commands=reload" .It Cm restart Runs the .Cm stop method, then the .Cm start method. .It Cm status Show the PID of .Va command , or some other script specific status operation. .It Cm poll Wait for .Va command to exit. .It Cm rcvar Display which .Xr rc.conf 5 variable is used (if any). This method always works, even if the appropriate .Xr rc.conf 5 variable is set to .Dq Li NO . .El .Pp The following variables are available to the methods (such as .Ar argument Ns Va _cmd ) as well as after .Ic run_rc_command has completed: .Bl -tag -width ".Va rc_flags" -offset indent .It Va rc_arg Argument provided to .Ic run_rc_command , after fast and force processing has been performed. .It Va rc_flags Flags to start the default command with. Defaults to .Va ${name}_flags , unless overridden by the environment variable .Sq Ev flags . This variable may be changed by the .Ar argument Ns Va _precmd method. .It Va rc_pid PID of .Va command (if appropriate). .It Va rc_fast Not empty if .Dq Li fast prefix was used. .It Va rc_force Not empty if .Dq Li force prefix was used. .El .It Ic run_rc_script Ar file argument Start the script .Ar file with an argument of .Ar argument , and handle the return value from the script. .Pp Various shell variables are unset before .Ar file is started: .Bd -ragged -offset indent .Va name , .Va command , .Va command_args , .Va command_interpreter , .Va extra_commands , .Va pidfile , .Va rcvar , .Va required_dirs , .Va required_files , .Va required_vars , .Ar argument Ns Va _cmd , .Ar argument Ns Va _precmd . .Ar argument Ns Va _postcmd . .Ed .Pp The startup behaviour of .Ar file depends upon the following checks: .Bl -enum .It If .Ar file ends in .Pa .sh , it is sourced into the current shell. .It If .Ar file appears to be a backup or scratch file (e.g., with a suffix of .Pa ~ , # , .OLD , or .Pa .orig ) , ignore it. .It If .Ar file is not executable, ignore it. .It If the .Xr rc.conf 5 variable .Va rc_fast_and_loose is empty, source .Ar file in a sub shell, otherwise source .Ar file into the current shell. .El +.It Ic stop_boot Op Ar always +Prevent booting to multiuser mode. +If the +.Sy autoboot +variable is +.Sq yes , +or +.Ar always +is +.Sq true , +then a +.Sy SIGTERM +signal is sent to the parent +process (which is assumed to be +.Xr rc 8 ). +Otherwise, the shell exits with status +.Li 1 . .It Ic set_rcvar Op Ar base Set the variable name required to start a service. In .Fx a daemon is usually controlled by an .Xr rc.conf 5 variable consisting of a daemon's name postfixed by the string .Dq Li "_enable" . This is not the case in .Nx . When the following line is included in a script: .Pp .Dl "rcvar=`set_rcvar`" .Pp this function will use the value of the .Va $name variable, which should be defined by the calling script, to construct the appropriate .Xr rc.conf 5 knob. If the .Ar base argument is set it will use .Ar base instead of .Va $name . .It Ic wait_for_pids Op Ar pid ... Wait until all of the provided .Ar pids do not exist any more, printing the list of outstanding .Ar pids every two seconds. .It Ic warn Ar message Display a warning message to .Va stderr and log it to the system log using .Xr logger 1 . The warning message consists of the script name (from .Va $0 ) , followed by .Dq Li ": WARNING: " , and then .Ar message . .El .Sh FILES .Bl -tag -width ".Pa /etc/rc.subr" -compact .It Pa /etc/rc.subr The .Nm file resides in .Pa /etc . .El .Sh SEE ALSO .Xr rc.conf 5 , .Xr rc 8 .Sh HISTORY The .Nm script appeared in .Nx 1.3 . The .Xr rc.d 8 support functions appeared in .Nx 1.5 . The .Nm script first appeared in .Fx 5.0 .