[Midnightbsd-cvs] src: rc.subr: Add kld loader functions and make several changes with
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Sat Jan 17 19:36:38 EST 2009
Log Message:
-----------
Add kld loader functions and make several changes with mounting
Modified Files:
--------------
src/etc:
rc.subr (r1.10 -> r1.11)
-------------- next part --------------
Index: rc.subr
===================================================================
RCS file: /home/cvs/src/etc/rc.subr,v
retrieving revision 1.10
retrieving revision 1.11
diff -L etc/rc.subr -L etc/rc.subr -u -r1.10 -r1.11
--- etc/rc.subr
+++ etc/rc.subr
@@ -41,6 +41,7 @@
#
: ${rcvar_manpage:='rc.conf(5)'}
+: ${RC_PID:=$$}; export RC_PID
#
# Operating System dependent/independent variables
@@ -55,7 +56,8 @@
CMD_OSTYPE="${SYSCTL_N} kern.ostype"
OSTYPE=`${CMD_OSTYPE}`
ID="/usr/bin/id"
-JID=`ps -p $$ -o jid=`
+PS="/bin/ps -ww"
+JID=`$PS -p $$ -o jid=`
IDCMD="if [ -x $ID ]; then $ID -un; fi"
SYSCTL_W="${SYSCTL}"
@@ -144,6 +146,27 @@
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
@@ -244,16 +267,30 @@
_pref=
if [ $_interpreter != "." ]; then # an interpreted script
- read _interp < $_procname # read interpreter name
- _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"
+ _script=${_chroot}${_chroot:+"/"}$_procname
+ if [ -r $_script ]; then
+ read _interp < $_script # read interpreter name
+ case "$_interp" in
+ \#!*)
+ _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
+ ;;
+ *)
+ warn "no shebang line in $_script"
+ set -- $_interpreter
+ ;;
+ esac
+ else
+ warn "cannot read shebang line from $_script"
+ set -- $_interpreter
fi
_interp="$* $_procname" # cleanup spaces, add _procname
_interpbn=${1##*/}
@@ -267,13 +304,10 @@
$_procname|$_procnamebn|${_procnamebn}:|"(${_procnamebn})"|"[${_procnamebn}]")'
fi
- _proccheck='
- ps 2>/dev/null -o "pid,jid,command" '"$_psargs"' |
+ _proccheck="\
+ $PS 2>/dev/null -o pid= -o jid= -o command= $_psargs"' |
while read _npid _jid '"$_fp_args"'; do
- case "$_npid" in
- PID)
- continue;;
- esac; '"$_fp_match"'
+ '"$_fp_match"'
if [ "$JID" -eq "$_jid" ];
then echo -n "$_pref$_npid";
_pref=" ";
@@ -399,12 +433,25 @@
# returned a zero exit code.
#
# required_dirs n If set, check for the existence of the given
-# directories before running the default
-# (re)start command.
+# directories before running a (re)start command.
#
# required_files n If set, check for the readability of the given
-# files before running the default (re)start
-# command.
+# 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
@@ -553,49 +600,31 @@
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
+ eval _cmd=\$${rc_arg}_cmd \
+ _precmd=\$${rc_arg}_precmd \
+ _postcmd=\$${rc_arg}_postcmd
+
if [ -n "$_cmd" ]; then
- # if the precmd failed and force
- # isn't set, exit
- #
- if [ -n "$_precmd" ]; then
- debug "run_rc_command: evaluating ${_precmd}()."
- eval $_precmd $rc_extra_args
- _return=$?
- [ $_return -ne 0 ] && [ -z "$rc_force" ] &&
- return 1
- fi
-
- if [ -n "$_cmd" ]; then
- debug "run_rc_command: evaluating ${_cmd}()."
- eval $_cmd $rc_extra_args
- _return=$?
- [ $_return -ne 0 ] && [ -z "$rc_force" ] &&
- return 1
- fi
-
- if [ -n "$_postcmd" ]; then
- debug "run_rc_command: evaluating ${_postcmd}()."
- eval $_postcmd $rc_extra_args
- _return=$?
- fi
+ _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)
@@ -604,51 +633,14 @@
return 1
fi
- if [ ! -x ${_chroot}${command} ]; then
- info "run_rc_command: cannot run ($command)."
+ if [ ! -x ${_chroot}${_chroot:+"/"}${command} ]; then
+ warn "run_rc_command: cannot run $command"
return 1
fi
- # check for required variables,
- # directories, and files
- #
- 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
-
- # if the precmd failed and force
- # isn't set, exit
- #
- if [ -n "${_precmd}" ]; then
- debug "run_rc_command: evaluating ${_precmd}()."
- eval $_precmd
- _return=$?
- [ $_return -ne 0 ] && [ -z "$rc_force" ] &&
- return 1
- fi
+ _run_rc_precmd || return 1
- # setup the command to run, and run it
+ # setup the full command to run
#
echo "Starting ${name}."
if [ -n "$_chroot" ]; then
@@ -671,105 +663,52 @@
fi
fi
- # if the cmd failed and force
- # isn't set, exit
+ # run the full command
#
- debug "run_rc_command: _doit: $_doit"
- eval $_doit
- _return=$?
- [ $_return -ne 0 ] && [ -z "$rc_force" ] && return 1
+ _run_rc_doit "$_doit" || return 1
# finally, run postcmd
#
- if [ -n "${_postcmd}" ]; then
- debug "run_rc_command: evaluating ${_postcmd}()."
- eval $_postcmd
- fi
+ _run_rc_postcmd
;;
stop)
if [ -z "$rc_pid" ]; then
[ -n "$rc_fast" ] && return 0
- if [ -n "$pidfile" ]; then
- echo 1>&2 \
- "${name} not running? (check $pidfile)."
- else
- echo 1>&2 "${name} not running?"
- fi
+ _run_rc_notrunning
return 1
fi
- # if the precmd failed and force
- # isn't set, exit
- #
- if [ -n "$_precmd" ]; then
- eval $_precmd
- _return=$?
- [ $_return -ne 0 ] && [ -z "$rc_force" ] &&
- return 1
- fi
+ _run_rc_precmd || return 1
# send the signal to stop
#
echo "Stopping ${name}."
- _doit="kill -${sig_stop:-TERM} $rc_pid"
- if [ -n "$_user" ]; then
- _doit="su -m $_user -c 'sh -c \"$_doit\"'"
- fi
-
- # if the stop cmd failed and force
- # isn't set, exit
- #
- eval $_doit
- _return=$?
- [ $_return -ne 0 ] && [ -z "$rc_force" ] && return 1
+ _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
- if [ -n "$_postcmd" ]; then
- eval $_postcmd
- _return=$?
- fi
+
+ _run_rc_postcmd
;;
reload)
if [ -z "$rc_pid" ]; then
- if [ -n "$pidfile" ]; then
- echo 1>&2 \
- "${name} not running? (check $pidfile)."
- else
- echo 1>&2 "${name} not running?"
- fi
+ _run_rc_notrunning
return 1
fi
- echo "Reloading ${name} config files."
- if [ -n "$_precmd" ]; then
- eval $_precmd
- _return=$?
- [ $_return -ne 0 ] && [ -z "$rc_force" ] &&
- return 1
- fi
- _doit="kill -${sig_reload:-HUP} $rc_pid"
- if [ -n "$_user" ]; then
- _doit="su -m $_user -c 'sh -c \"$_doit\"'"
- fi
- eval $_doit
- _return=$?
- [ $_return -ne 0 ] && [ -z "$rc_force" ] && return 1
- if [ -n "$_postcmd" ]; then
- eval $_postcmd
- _return=$?
- fi
+
+ _run_rc_precmd || return 1
+
+ _doit=$(_run_rc_killcmd "${sig_reload:-HUP}")
+ _run_rc_doit "$_doit" || return 1
+
+ _run_rc_postcmd
;;
restart)
- if [ -n "$_precmd" ]; then
- eval $_precmd $rc_extra_args
- _return=$?
- [ $_return -ne 0 ] && [ -z "$rc_force" ] &&
- return 1
- fi
# prevent restart being called more
# than once by any given script
#
@@ -778,29 +717,32 @@
fi
_rc_restart_done=true
- # run stop in a subshell to keep variables for start
+ _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
+ ( run_rc_command ${_rc_prefix}start $rc_extra_args )
+ _return=$?
+ [ $_return -ne 0 ] && [ -z "$rc_force" ] && return 1
- if [ -n "$_postcmd" ]; then
- eval $_postcmd $rc_extra_args
- _return=$?
- fi
+ _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"
+ echo "${rcvar}=YES"
else
- echo "\$${rcvar}=NO"
+ echo "${rcvar}=NO"
fi
fi
;;
@@ -819,6 +761,83 @@
}
#
+# 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
@@ -1094,7 +1113,7 @@
return 1
fi
if [ ! -d "$linkdir" ]; then
- warn "$_me: the directory $linkdir does not exist"
+ warn "$_me: the directory $linkdir does not exist."
return 1
fi
if ! ln -sf $src $link; then
@@ -1309,6 +1328,53 @@
/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
@@ -1413,6 +1479,74 @@
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=:
More information about the Midnightbsd-cvs
mailing list