rc.subr revision 230007
1# $NetBSD: rc.subr,v 1.67 2006/10/07 11:25:15 elad Exp $ 2# $FreeBSD: head/etc/rc.subr 230007 2012-01-12 06:48:11Z rea $ 3# 4# Copyright (c) 1997-2004 The NetBSD Foundation, Inc. 5# All rights reserved. 6# 7# This code is derived from software contributed to The NetBSD Foundation 8# by Luke Mewburn. 9# 10# Redistribution and use in source and binary forms, with or without 11# modification, are permitted provided that the following conditions 12# are met: 13# 1. Redistributions of source code must retain the above copyright 14# notice, this list of conditions and the following disclaimer. 15# 2. Redistributions in binary form must reproduce the above copyright 16# notice, this list of conditions and the following disclaimer in the 17# documentation and/or other materials provided with the distribution. 18# 19# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29# POSSIBILITY OF SUCH DAMAGE. 30# 31# rc.subr 32# functions used by various rc scripts 33# 34 35: ${RC_PID:=$$}; export RC_PID 36 37# 38# Operating System dependent/independent variables 39# 40 41if [ -z "${_rc_subr_loaded}" ]; then 42 43_rc_subr_loaded="YES" 44 45SYSCTL="/sbin/sysctl" 46SYSCTL_N="${SYSCTL} -n" 47SYSCTL_W="${SYSCTL}" 48ID="/usr/bin/id" 49IDCMD="if [ -x $ID ]; then $ID -un; fi" 50PS="/bin/ps -ww" 51JID=`$PS -p $$ -o jid=` 52 53# 54# functions 55# --------- 56 57# set_rcvar [var] [defval] [desc] 58# 59# Echo or define a rc.conf(5) variable name. Global variable 60# $rcvars is used. 61# 62# If no argument is specified, echo "${name}_enable". 63# 64# If only a var is specified, echo "${var}_enable". 65# 66# If var and defval are specified, the ${var} is defined as 67# rc.conf(5) variable and the default value is ${defvar}. An 68# optional argument $desc can also be specified to add a 69# description for that. 70# 71set_rcvar() 72{ 73 case $# in 74 0) 75 echo ${name}_enable 76 ;; 77 1) 78 echo ${1}_enable 79 ;; 80 *) 81 debug "rcvar_define: \$$1=$2 is added" \ 82 " as a rc.conf(5) variable." 83 84 local _var 85 _var=$1 86 rcvars="${rcvars# } $_var" 87 eval ${_var}_defval=\"$2\" 88 shift 2 89 # encode multiple lines of _desc 90 for l in "$@"; do 91 eval ${_var}_desc=\"\${${_var}_desc#^^}^^$l\" 92 done 93 eval ${_var}_desc=\"\${${_var}_desc#^^}\" 94 ;; 95 esac 96} 97 98# set_rcvar_obsolete oldvar [newvar] [msg] 99# Define obsolete variable. 100# Global variable $rcvars_obsolete is used. 101# 102set_rcvar_obsolete() 103{ 104 local _var 105 _var=$1 106 debug "rcvar_obsolete: \$$1(old) -> \$$2(new) is defined" 107 108 rcvars_obsolete="${rcvars_obsolete# } $1" 109 eval ${1}_newvar=\"$2\" 110 shift 2 111 eval ${_var}_obsolete_msg=\"$*\" 112} 113 114# 115# force_depend script 116# Force a service to start. Intended for use by services 117# to resolve dependency issues. It is assumed the caller 118# has check to make sure this call is necessary 119# $1 - filename of script, in /etc/rc.d, to run 120# 121force_depend() 122{ 123 _depend="$1" 124 125 info "${name} depends on ${_depend}, which will be forced to start." 126 if ! /etc/rc.d/${_depend} forcestart; then 127 warn "Unable to force ${_depend}. It may already be running." 128 return 1 129 fi 130 return 0 131} 132 133# 134# checkyesno var 135# Test $1 variable, and warn if not set to YES or NO. 136# Return 0 if it's "yes" (et al), nonzero otherwise. 137# 138checkyesno() 139{ 140 eval _value=\$${1} 141 debug "checkyesno: $1 is set to $_value." 142 case $_value in 143 144 # "yes", "true", "on", or "1" 145 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 146 return 0 147 ;; 148 149 # "no", "false", "off", or "0" 150 [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) 151 return 1 152 ;; 153 *) 154 warn "\$${1} is not set properly - see rc.conf(5)." 155 return 1 156 ;; 157 esac 158} 159 160# 161# reverse_list list 162# print the list in reverse order 163# 164reverse_list() 165{ 166 _revlist= 167 for _revfile; do 168 _revlist="$_revfile $_revlist" 169 done 170 echo $_revlist 171} 172 173# stop_boot always 174# If booting directly to multiuser or $always is enabled, 175# send SIGTERM to the parent (/etc/rc) to abort the boot. 176# Otherwise just exit. 177# 178stop_boot() 179{ 180 local always 181 182 case $1 in 183 # "yes", "true", "on", or "1" 184 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 185 always=true 186 ;; 187 *) 188 always=false 189 ;; 190 esac 191 if [ "$autoboot" = yes -o "$always" = true ]; then 192 echo "ERROR: ABORTING BOOT (sending SIGTERM to parent)!" 193 kill -TERM ${RC_PID} 194 fi 195 exit 1 196} 197 198# 199# mount_critical_filesystems type 200# Go through the list of critical filesystems as provided in 201# the rc.conf(5) variable $critical_filesystems_${type}, checking 202# each one to see if it is mounted, and if it is not, mounting it. 203# 204mount_critical_filesystems() 205{ 206 eval _fslist=\$critical_filesystems_${1} 207 for _fs in $_fslist; do 208 mount | ( 209 _ismounted=false 210 while read what _on on _type type; do 211 if [ $on = $_fs ]; then 212 _ismounted=true 213 fi 214 done 215 if $_ismounted; then 216 : 217 else 218 mount $_fs >/dev/null 2>&1 219 fi 220 ) 221 done 222} 223 224# 225# check_pidfile pidfile procname [interpreter] 226# Parses the first line of pidfile for a PID, and ensures 227# that the process is running and matches procname. 228# Prints the matching PID upon success, nothing otherwise. 229# interpreter is optional; see _find_processes() for details. 230# 231check_pidfile() 232{ 233 _pidfile=$1 234 _procname=$2 235 _interpreter=$3 236 if [ -z "$_pidfile" -o -z "$_procname" ]; then 237 err 3 'USAGE: check_pidfile pidfile procname [interpreter]' 238 fi 239 if [ ! -f $_pidfile ]; then 240 debug "pid file ($_pidfile): not readable." 241 return 242 fi 243 read _pid _junk < $_pidfile 244 if [ -z "$_pid" ]; then 245 debug "pid file ($_pidfile): no pid in file." 246 return 247 fi 248 _find_processes $_procname ${_interpreter:-.} '-p '"$_pid" 249} 250 251# 252# check_process procname [interpreter] 253# Ensures that a process (or processes) named procname is running. 254# Prints a list of matching PIDs. 255# interpreter is optional; see _find_processes() for details. 256# 257check_process() 258{ 259 _procname=$1 260 _interpreter=$2 261 if [ -z "$_procname" ]; then 262 err 3 'USAGE: check_process procname [interpreter]' 263 fi 264 _find_processes $_procname ${_interpreter:-.} '-ax' 265} 266 267# 268# _find_processes procname interpreter psargs 269# Search for procname in the output of ps generated by psargs. 270# Prints the PIDs of any matching processes, space separated. 271# 272# If interpreter == ".", check the following variations of procname 273# against the first word of each command: 274# procname 275# `basename procname` 276# `basename procname` + ":" 277# "(" + `basename procname` + ")" 278# "[" + `basename procname` + "]" 279# 280# If interpreter != ".", read the first line of procname, remove the 281# leading #!, normalise whitespace, append procname, and attempt to 282# match that against each command, either as is, or with extra words 283# at the end. As an alternative, to deal with interpreted daemons 284# using perl, the basename of the interpreter plus a colon is also 285# tried as the prefix to procname. 286# 287_find_processes() 288{ 289 if [ $# -ne 3 ]; then 290 err 3 'USAGE: _find_processes procname interpreter psargs' 291 fi 292 _procname=$1 293 _interpreter=$2 294 _psargs=$3 295 296 _pref= 297 if [ $_interpreter != "." ]; then # an interpreted script 298 _script=${_chroot}${_chroot:+"/"}$_procname 299 if [ -r $_script ]; then 300 read _interp < $_script # read interpreter name 301 case "$_interp" in 302 \#!*) 303 _interp=${_interp#\#!} # strip #! 304 set -- $_interp 305 case $1 in 306 */bin/env) 307 shift # drop env to get real name 308 ;; 309 esac 310 if [ $_interpreter != $1 ]; then 311 warn "\$command_interpreter $_interpreter != $1" 312 fi 313 ;; 314 *) 315 warn "no shebang line in $_script" 316 set -- $_interpreter 317 ;; 318 esac 319 else 320 warn "cannot read shebang line from $_script" 321 set -- $_interpreter 322 fi 323 _interp="$* $_procname" # cleanup spaces, add _procname 324 _interpbn=${1##*/} 325 _fp_args='_argv' 326 _fp_match='case "$_argv" in 327 ${_interp}|"${_interp} "*|"${_interpbn}: ${_procname}"*)' 328 else # a normal daemon 329 _procnamebn=${_procname##*/} 330 _fp_args='_arg0 _argv' 331 _fp_match='case "$_arg0" in 332 $_procname|$_procnamebn|${_procnamebn}:|"(${_procnamebn})"|"[${_procnamebn}]")' 333 fi 334 335 _proccheck="\ 336 $PS 2>/dev/null -o pid= -o jid= -o command= $_psargs"' | 337 while read _npid _jid '"$_fp_args"'; do 338 '"$_fp_match"' 339 if [ "$JID" -eq "$_jid" ]; 340 then echo -n "$_pref$_npid"; 341 _pref=" "; 342 fi 343 ;; 344 esac 345 done' 346 347# debug "in _find_processes: proccheck is ($_proccheck)." 348 eval $_proccheck 349} 350 351# 352# wait_for_pids pid [pid ...] 353# spins until none of the pids exist 354# 355wait_for_pids() 356{ 357 local _list _prefix _nlist _j 358 359 _list="$@" 360 if [ -z "$_list" ]; then 361 return 362 fi 363 _prefix= 364 while true; do 365 _nlist=""; 366 for _j in $_list; do 367 if kill -0 $_j 2>/dev/null; then 368 _nlist="${_nlist}${_nlist:+ }$_j" 369 [ -n "$_prefix" ] && sleep 1 370 fi 371 done 372 if [ -z "$_nlist" ]; then 373 break 374 fi 375 _list=$_nlist 376 echo -n ${_prefix:-"Waiting for PIDS: "}$_list 377 _prefix=", " 378 pwait $_list 2>/dev/null 379 done 380 if [ -n "$_prefix" ]; then 381 echo "." 382 fi 383} 384 385# 386# get_pidfile_from_conf string file 387# 388# Takes a string to search for in the specified file. 389# Ignores lines with traditional comment characters. 390# 391# Example: 392# 393# if get_pidfile_from_conf string file; then 394# pidfile="$_pidfile_from_conf" 395# else 396# pidfile='appropriate default' 397# fi 398# 399get_pidfile_from_conf() 400{ 401 if [ -z "$1" -o -z "$2" ]; then 402 err 3 "USAGE: get_pidfile_from_conf string file ($name)" 403 fi 404 405 local string file line 406 407 string="$1" ; file="$2" 408 409 if [ ! -s "$file" ]; then 410 err 3 "get_pidfile_from_conf: $file does not exist ($name)" 411 fi 412 413 while read line; do 414 case "$line" in 415 *[#\;]*${string}*) continue ;; 416 *${string}*) break ;; 417 esac 418 done < $file 419 420 if [ -n "$line" ]; then 421 line=${line#*/} 422 _pidfile_from_conf="/${line%%[\"\;]*}" 423 else 424 return 1 425 fi 426} 427 428# 429# check_startmsgs 430# If rc_quiet is set (usually as a result of using faststart at 431# boot time) check if rc_startmsgs is enabled. 432# 433check_startmsgs() 434{ 435 if [ -n "$rc_quiet" ]; then 436 checkyesno rc_startmsgs 437 else 438 return 0 439 fi 440} 441 442# 443# run_rc_command argument 444# Search for argument in the list of supported commands, which is: 445# "start stop restart rcvar status poll ${extra_commands}" 446# If there's a match, run ${argument}_cmd or the default method 447# (see below). 448# 449# If argument has a given prefix, then change the operation as follows: 450# Prefix Operation 451# ------ --------- 452# fast Skip the pid check, and set rc_fast=yes, rc_quiet=yes 453# force Set ${rcvar} to YES, and set rc_force=yes 454# one Set ${rcvar} to YES 455# quiet Don't output some diagnostics, and set rc_quiet=yes 456# 457# The following globals are used: 458# 459# Name Needed Purpose 460# ---- ------ ------- 461# name y Name of script. 462# 463# command n Full path to command. 464# Not needed if ${rc_arg}_cmd is set for 465# each keyword. 466# 467# command_args n Optional args/shell directives for command. 468# 469# command_interpreter n If not empty, command is interpreted, so 470# call check_{pidfile,process}() appropriately. 471# 472# desc n Description of script. 473# 474# extra_commands n List of extra commands supported. 475# 476# pidfile n If set, use check_pidfile $pidfile $command, 477# otherwise use check_process $command. 478# In either case, only check if $command is set. 479# 480# procname n Process name to check for instead of $command. 481# 482# rcvar n This is checked with checkyesno to determine 483# if the action should be run. 484# 485# ${name}_program n Full path to command. 486# Meant to be used in /etc/rc.conf to override 487# ${command}. 488# 489# ${name}_chroot n Directory to chroot to before running ${command} 490# Requires /usr to be mounted. 491# 492# ${name}_chdir n Directory to cd to before running ${command} 493# (if not using ${name}_chroot). 494# 495# ${name}_flags n Arguments to call ${command} with. 496# NOTE: $flags from the parent environment 497# can be used to override this. 498# 499# ${name}_nice n Nice level to run ${command} at. 500# 501# ${name}_user n User to run ${command} as, using su(1) if not 502# using ${name}_chroot. 503# Requires /usr to be mounted. 504# 505# ${name}_group n Group to run chrooted ${command} as. 506# Requires /usr to be mounted. 507# 508# ${name}_groups n Comma separated list of supplementary groups 509# to run the chrooted ${command} with. 510# Requires /usr to be mounted. 511# 512# ${rc_arg}_cmd n If set, use this as the method when invoked; 513# Otherwise, use default command (see below) 514# 515# ${rc_arg}_precmd n If set, run just before performing the 516# ${rc_arg}_cmd method in the default 517# operation (i.e, after checking for required 518# bits and process (non)existence). 519# If this completes with a non-zero exit code, 520# don't run ${rc_arg}_cmd. 521# 522# ${rc_arg}_postcmd n If set, run just after performing the 523# ${rc_arg}_cmd method, if that method 524# returned a zero exit code. 525# 526# required_dirs n If set, check for the existence of the given 527# directories before running a (re)start command. 528# 529# required_files n If set, check for the readability of the given 530# files before running a (re)start command. 531# 532# required_modules n If set, ensure the given kernel modules are 533# loaded before running a (re)start command. 534# The check and possible loads are actually 535# done after start_precmd so that the modules 536# aren't loaded in vain, should the precmd 537# return a non-zero status to indicate a error. 538# If a word in the list looks like "foo:bar", 539# "foo" is the KLD file name and "bar" is the 540# module name. If a word looks like "foo~bar", 541# "foo" is the KLD file name and "bar" is a 542# egrep(1) pattern matching the module name. 543# Otherwise the module name is assumed to be 544# the same as the KLD file name, which is most 545# common. See load_kld(). 546# 547# required_vars n If set, perform checkyesno on each of the 548# listed variables before running the default 549# (re)start command. 550# 551# Default behaviour for a given argument, if no override method is 552# provided: 553# 554# Argument Default behaviour 555# -------- ----------------- 556# start if !running && checkyesno ${rcvar} 557# ${command} 558# 559# stop if ${pidfile} 560# rc_pid=$(check_pidfile $pidfile $command) 561# else 562# rc_pid=$(check_process $command) 563# kill $sig_stop $rc_pid 564# wait_for_pids $rc_pid 565# ($sig_stop defaults to TERM.) 566# 567# reload Similar to stop, except use $sig_reload instead, 568# and doesn't wait_for_pids. 569# $sig_reload defaults to HUP. 570# Note that `reload' isn't provided by default, 571# it should be enabled via $extra_commands. 572# 573# restart Run `stop' then `start'. 574# 575# status Show if ${command} is running, etc. 576# 577# poll Wait for ${command} to exit. 578# 579# rcvar Display what rc.conf variable is used (if any). 580# 581# Variables available to methods, and after run_rc_command() has 582# completed: 583# 584# Variable Purpose 585# -------- ------- 586# rc_arg Argument to command, after fast/force/one processing 587# performed 588# 589# rc_flags Flags to start the default command with. 590# Defaults to ${name}_flags, unless overridden 591# by $flags from the environment. 592# This variable may be changed by the precmd method. 593# 594# rc_pid PID of command (if appropriate) 595# 596# rc_fast Not empty if "fast" was provided (q.v.) 597# 598# rc_force Not empty if "force" was provided (q.v.) 599# 600# rc_quiet Not empty if "quiet" was provided 601# 602# 603run_rc_command() 604{ 605 _return=0 606 rc_arg=$1 607 if [ -z "$name" ]; then 608 err 3 'run_rc_command: $name is not set.' 609 fi 610 611 # Don't repeat the first argument when passing additional command- 612 # line arguments to the command subroutines. 613 # 614 shift 1 615 rc_extra_args="$*" 616 617 _rc_prefix= 618 case "$rc_arg" in 619 fast*) # "fast" prefix; don't check pid 620 rc_arg=${rc_arg#fast} 621 rc_fast=yes 622 rc_quiet=yes 623 ;; 624 force*) # "force" prefix; always run 625 rc_force=yes 626 _rc_prefix=force 627 rc_arg=${rc_arg#${_rc_prefix}} 628 if [ -n "${rcvar}" ]; then 629 eval ${rcvar}=YES 630 fi 631 ;; 632 one*) # "one" prefix; set ${rcvar}=yes 633 _rc_prefix=one 634 rc_arg=${rc_arg#${_rc_prefix}} 635 if [ -n "${rcvar}" ]; then 636 eval ${rcvar}=YES 637 fi 638 ;; 639 quiet*) # "quiet" prefix; omit some messages 640 _rc_prefix=quiet 641 rc_arg=${rc_arg#${_rc_prefix}} 642 rc_quiet=yes 643 ;; 644 esac 645 646 eval _override_command=\$${name}_program 647 command=${_override_command:-$command} 648 649 _keywords="start stop restart rcvar $extra_commands" 650 rc_pid= 651 _pidcmd= 652 _procname=${procname:-${command}} 653 654 # setup pid check command 655 if [ -n "$_procname" ]; then 656 if [ -n "$pidfile" ]; then 657 _pidcmd='rc_pid=$(check_pidfile '"$pidfile $_procname $command_interpreter"')' 658 else 659 _pidcmd='rc_pid=$(check_process '"$_procname $command_interpreter"')' 660 fi 661 if [ -n "$_pidcmd" ]; then 662 _keywords="${_keywords} status poll" 663 fi 664 fi 665 666 if [ -z "$rc_arg" ]; then 667 rc_usage $_keywords 668 fi 669 670 if [ -n "$flags" ]; then # allow override from environment 671 rc_flags=$flags 672 else 673 eval rc_flags=\$${name}_flags 674 fi 675 eval _chdir=\$${name}_chdir _chroot=\$${name}_chroot \ 676 _nice=\$${name}_nice _user=\$${name}_user \ 677 _group=\$${name}_group _groups=\$${name}_groups 678 679 if [ -n "$_user" ]; then # unset $_user if running as that user 680 if [ "$_user" = "$(eval $IDCMD)" ]; then 681 unset _user 682 fi 683 fi 684 685 eval $_pidcmd # determine the pid if necessary 686 687 for _elem in $_keywords; do 688 if [ "$_elem" != "$rc_arg" ]; then 689 continue 690 fi 691 # if ${rcvar} is set, $1 is not "rcvar" 692 # and ${rc_pid} is not set, then run 693 # checkyesno ${rcvar} 694 # and return if that failed 695 # 696 if [ -n "${rcvar}" -a "$rc_arg" != "rcvar" -a "$rc_arg" != "stop" ] || 697 [ -n "${rcvar}" -a "$rc_arg" = "stop" -a -z "${rc_pid}" ]; then 698 if ! checkyesno ${rcvar}; then 699 if [ -n "${rc_quiet}" ]; then 700 return 0 701 fi 702 echo -n "Cannot '${rc_arg}' $name. Set ${rcvar} to " 703 echo -n "YES in /etc/rc.conf or use 'one${rc_arg}' " 704 echo "instead of '${rc_arg}'." 705 return 0 706 fi 707 fi 708 709 # if there's a custom ${XXX_cmd}, 710 # run that instead of the default 711 # 712 eval _cmd=\$${rc_arg}_cmd \ 713 _precmd=\$${rc_arg}_precmd \ 714 _postcmd=\$${rc_arg}_postcmd 715 716 if [ -n "$_cmd" ]; then 717 _run_rc_precmd || return 1 718 _run_rc_doit "$_cmd $rc_extra_args" || return 1 719 _run_rc_postcmd 720 return $_return 721 fi 722 723 case "$rc_arg" in # default operations... 724 725 status) 726 _run_rc_precmd || return 1 727 if [ -n "$rc_pid" ]; then 728 echo "${name} is running as pid $rc_pid." 729 else 730 echo "${name} is not running." 731 return 1 732 fi 733 _run_rc_postcmd 734 ;; 735 736 start) 737 if [ -z "$rc_fast" -a -n "$rc_pid" ]; then 738 echo 1>&2 "${name} already running? (pid=$rc_pid)." 739 return 1 740 fi 741 742 if [ ! -x ${_chroot}${_chroot:+"/"}${command} ]; then 743 warn "run_rc_command: cannot run $command" 744 return 1 745 fi 746 747 if ! _run_rc_precmd; then 748 warn "failed precmd routine for ${name}" 749 return 1 750 fi 751 752 # setup the full command to run 753 # 754 check_startmsgs && echo "Starting ${name}." 755 if [ -n "$_chroot" ]; then 756 _doit="\ 757${_nice:+nice -n $_nice }\ 758chroot ${_user:+-u $_user }${_group:+-g $_group }${_groups:+-G $_groups }\ 759$_chroot $command $rc_flags $command_args" 760 else 761 _doit="\ 762${_chdir:+cd $_chdir && }\ 763$command $rc_flags $command_args" 764 if [ -n "$_user" ]; then 765 _doit="su -m $_user -c 'sh -c \"$_doit\"'" 766 fi 767 if [ -n "$_nice" ]; then 768 if [ -z "$_user" ]; then 769 _doit="sh -c \"$_doit\"" 770 fi 771 _doit="nice -n $_nice $_doit" 772 fi 773 fi 774 775 # run the full command 776 # 777 if ! _run_rc_doit "$_doit"; then 778 warn "failed to start ${name}" 779 return 1 780 fi 781 782 # finally, run postcmd 783 # 784 _run_rc_postcmd 785 ;; 786 787 stop) 788 if [ -z "$rc_pid" ]; then 789 [ -n "$rc_fast" ] && return 0 790 _run_rc_notrunning 791 return 1 792 fi 793 794 _run_rc_precmd || return 1 795 796 # send the signal to stop 797 # 798 echo "Stopping ${name}." 799 _doit=$(_run_rc_killcmd "${sig_stop:-TERM}") 800 _run_rc_doit "$_doit" || return 1 801 802 # wait for the command to exit, 803 # and run postcmd. 804 wait_for_pids $rc_pid 805 806 _run_rc_postcmd 807 ;; 808 809 reload) 810 if [ -z "$rc_pid" ]; then 811 _run_rc_notrunning 812 return 1 813 fi 814 815 _run_rc_precmd || return 1 816 817 _doit=$(_run_rc_killcmd "${sig_reload:-HUP}") 818 _run_rc_doit "$_doit" || return 1 819 820 _run_rc_postcmd 821 ;; 822 823 restart) 824 # prevent restart being called more 825 # than once by any given script 826 # 827 if ${_rc_restart_done:-false}; then 828 return 0 829 fi 830 _rc_restart_done=true 831 832 _run_rc_precmd || return 1 833 834 # run those in a subshell to keep global variables 835 ( run_rc_command ${_rc_prefix}stop $rc_extra_args ) 836 ( run_rc_command ${_rc_prefix}start $rc_extra_args ) 837 _return=$? 838 [ $_return -ne 0 ] && [ -z "$rc_force" ] && return 1 839 840 _run_rc_postcmd 841 ;; 842 843 poll) 844 _run_rc_precmd || return 1 845 if [ -n "$rc_pid" ]; then 846 wait_for_pids $rc_pid 847 fi 848 _run_rc_postcmd 849 ;; 850 851 rcvar) 852 echo -n "# $name" 853 if [ -n "$desc" ]; then 854 echo " : $desc" 855 else 856 echo "" 857 fi 858 echo "#" 859 # Get unique vars in $rcvar $rcvars 860 for _v in $rcvar $rcvars; do 861 case $v in 862 $_v\ *|\ *$_v|*\ $_v\ *) ;; 863 *) v="${v# } $_v" ;; 864 esac 865 done 866 867 # Display variables. 868 for _v in $v; do 869 if [ -z "$_v" ]; then 870 continue 871 fi 872 873 eval _desc=\$${_v}_desc 874 eval _defval=\$${_v}_defval 875 _h="-" 876 877 eval echo \"$_v=\\\"\$$_v\\\"\" 878 # decode multiple lines of _desc 879 while [ -n "$_desc" ]; do 880 case $_desc in 881 *^^*) 882 echo "# $_h ${_desc%%^^*}" 883 _desc=${_desc#*^^} 884 _h=" " 885 ;; 886 *) 887 echo "# $_h ${_desc}" 888 break 889 ;; 890 esac 891 done 892 echo "# (default: \"$_defval\")" 893 done 894 echo "" 895 ;; 896 897 *) 898 rc_usage $_keywords 899 ;; 900 901 esac 902 return $_return 903 done 904 905 echo 1>&2 "$0: unknown directive '$rc_arg'." 906 rc_usage $_keywords 907 # not reached 908} 909 910# 911# Helper functions for run_rc_command: common code. 912# They use such global variables besides the exported rc_* ones: 913# 914# name R/W 915# ------------------ 916# _precmd R 917# _postcmd R 918# _return W 919# 920_run_rc_precmd() 921{ 922 check_required_before "$rc_arg" || return 1 923 924 if [ -n "$_precmd" ]; then 925 debug "run_rc_command: ${rc_arg}_precmd: $_precmd $rc_extra_args" 926 eval "$_precmd $rc_extra_args" 927 _return=$? 928 929 # If precmd failed and force isn't set, request exit. 930 if [ $_return -ne 0 ] && [ -z "$rc_force" ]; then 931 return 1 932 fi 933 fi 934 935 check_required_after "$rc_arg" || return 1 936 937 return 0 938} 939 940_run_rc_postcmd() 941{ 942 if [ -n "$_postcmd" ]; then 943 debug "run_rc_command: ${rc_arg}_postcmd: $_postcmd $rc_extra_args" 944 eval "$_postcmd $rc_extra_args" 945 _return=$? 946 fi 947 return 0 948} 949 950_run_rc_doit() 951{ 952 debug "run_rc_command: doit: $*" 953 eval "$@" 954 _return=$? 955 956 # If command failed and force isn't set, request exit. 957 if [ $_return -ne 0 ] && [ -z "$rc_force" ]; then 958 return 1 959 fi 960 961 return 0 962} 963 964_run_rc_notrunning() 965{ 966 local _pidmsg 967 968 if [ -n "$pidfile" ]; then 969 _pidmsg=" (check $pidfile)." 970 else 971 _pidmsg= 972 fi 973 echo 1>&2 "${name} not running?${_pidmsg}" 974} 975 976_run_rc_killcmd() 977{ 978 local _cmd 979 980 _cmd="kill -$1 $rc_pid" 981 if [ -n "$_user" ]; then 982 _cmd="su -m ${_user} -c 'sh -c \"${_cmd}\"'" 983 fi 984 echo "$_cmd" 985} 986 987# 988# run_rc_script file arg 989# Start the script `file' with `arg', and correctly handle the 990# return value from the script. 991# If `file' ends with `.sh', it's sourced into the current environment 992# when $rc_fast_and_loose is set, otherwise it is run as a child process. 993# If `file' appears to be a backup or scratch file, ignore it. 994# Otherwise if it is executable run as a child process. 995# 996run_rc_script() 997{ 998 _file=$1 999 _arg=$2 1000 if [ -z "$_file" -o -z "$_arg" ]; then 1001 err 3 'USAGE: run_rc_script file arg' 1002 fi 1003 1004 unset name command command_args command_interpreter \ 1005 extra_commands pidfile procname \ 1006 rcvar rcvars rcvars_obsolete required_dirs required_files \ 1007 required_vars 1008 eval unset ${_arg}_cmd ${_arg}_precmd ${_arg}_postcmd 1009 1010 case "$_file" in 1011 /etc/rc.d/*.sh) # no longer allowed in the base 1012 warn "Ignoring old-style startup script $_file" 1013 ;; 1014 *[~#]|*.OLD|*.bak|*.orig|*,v) # scratch file; skip 1015 warn "Ignoring scratch file $_file" 1016 ;; 1017 *) # run in subshell 1018 if [ -x $_file ]; then 1019 if [ -n "$rc_fast_and_loose" ]; then 1020 set $_arg; . $_file 1021 else 1022 ( trap "echo Script $_file interrupted; kill -QUIT $$" 3 1023 trap "echo Script $_file interrupted; exit 1" 2 1024 trap "echo Script $_file running" 29 1025 set $_arg; . $_file ) 1026 fi 1027 fi 1028 ;; 1029 esac 1030} 1031 1032# 1033# load_rc_config name 1034# Source in the configuration file for a given name. 1035# 1036load_rc_config() 1037{ 1038 local _name _var _defval _v _msg _new 1039 _name=$1 1040 if [ -z "$_name" ]; then 1041 err 3 'USAGE: load_rc_config name' 1042 fi 1043 1044 if ${_rc_conf_loaded:-false}; then 1045 : 1046 else 1047 if [ -r /etc/defaults/rc.conf ]; then 1048 debug "Sourcing /etc/defaults/rc.conf" 1049 . /etc/defaults/rc.conf 1050 source_rc_confs 1051 elif [ -r /etc/rc.conf ]; then 1052 debug "Sourcing /etc/rc.conf (/etc/defaults/rc.conf doesn't exist)." 1053 . /etc/rc.conf 1054 fi 1055 _rc_conf_loaded=true 1056 fi 1057 if [ -f /etc/rc.conf.d/"$_name" ]; then 1058 debug "Sourcing /etc/rc.conf.d/${_name}" 1059 . /etc/rc.conf.d/"$_name" 1060 fi 1061 1062 # Set defaults if defined. 1063 for _var in $rcvar $rcvars; do 1064 eval _defval=\$${_var}_defval 1065 if [ -n "$_defval" ]; then 1066 eval : \${$_var:=\$${_var}_defval} 1067 fi 1068 done 1069 1070 # check obsolete rc.conf variables 1071 for _var in $rcvars_obsolete; do 1072 eval _v=\$$_var 1073 eval _msg=\$${_var}_obsolete_msg 1074 eval _new=\$${_var}_newvar 1075 case $_v in 1076 "") 1077 ;; 1078 *) 1079 if [ -z "$_new" ]; then 1080 _msg="Ignored." 1081 else 1082 eval $_new=\"\$$_var\" 1083 if [ -z "$_msg" ]; then 1084 _msg="Use \$$_new instead." 1085 fi 1086 fi 1087 warn "\$$_var is obsolete. $_msg" 1088 ;; 1089 esac 1090 done 1091} 1092 1093# 1094# load_rc_config_var name var 1095# Read the rc.conf(5) var for name and set in the 1096# current shell, using load_rc_config in a subshell to prevent 1097# unwanted side effects from other variable assignments. 1098# 1099load_rc_config_var() 1100{ 1101 if [ $# -ne 2 ]; then 1102 err 3 'USAGE: load_rc_config_var name var' 1103 fi 1104 eval $(eval '( 1105 load_rc_config '$1' >/dev/null; 1106 if [ -n "${'$2'}" -o "${'$2'-UNSET}" != "UNSET" ]; then 1107 echo '$2'=\'\''${'$2'}\'\''; 1108 fi 1109 )' ) 1110} 1111 1112# 1113# rc_usage commands 1114# Print a usage string for $0, with `commands' being a list of 1115# valid commands. 1116# 1117rc_usage() 1118{ 1119 echo -n 1>&2 "Usage: $0 [fast|force|one|quiet](" 1120 1121 _sep= 1122 for _elem; do 1123 echo -n 1>&2 "$_sep$_elem" 1124 _sep="|" 1125 done 1126 echo 1>&2 ")" 1127 exit 1 1128} 1129 1130# 1131# err exitval message 1132# Display message to stderr and log to the syslog, and exit with exitval. 1133# 1134err() 1135{ 1136 exitval=$1 1137 shift 1138 1139 if [ -x /usr/bin/logger ]; then 1140 logger "$0: ERROR: $*" 1141 fi 1142 echo 1>&2 "$0: ERROR: $*" 1143 exit $exitval 1144} 1145 1146# 1147# warn message 1148# Display message to stderr and log to the syslog. 1149# 1150warn() 1151{ 1152 if [ -x /usr/bin/logger ]; then 1153 logger "$0: WARNING: $*" 1154 fi 1155 echo 1>&2 "$0: WARNING: $*" 1156} 1157 1158# 1159# info message 1160# Display informational message to stdout and log to syslog. 1161# 1162info() 1163{ 1164 case ${rc_info} in 1165 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 1166 if [ -x /usr/bin/logger ]; then 1167 logger "$0: INFO: $*" 1168 fi 1169 echo "$0: INFO: $*" 1170 ;; 1171 esac 1172} 1173 1174# 1175# debug message 1176# If debugging is enabled in rc.conf output message to stderr. 1177# BEWARE that you don't call any subroutine that itself calls this 1178# function. 1179# 1180debug() 1181{ 1182 case ${rc_debug} in 1183 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 1184 if [ -x /usr/bin/logger ]; then 1185 logger "$0: DEBUG: $*" 1186 fi 1187 echo 1>&2 "$0: DEBUG: $*" 1188 ;; 1189 esac 1190} 1191 1192# 1193# backup_file action file cur backup 1194# Make a backup copy of `file' into `cur', and save the previous 1195# version of `cur' as `backup' or use rcs for archiving. 1196# 1197# This routine checks the value of the backup_uses_rcs variable, 1198# which can be either YES or NO. 1199# 1200# The `action' keyword can be one of the following: 1201# 1202# add `file' is now being backed up (and is possibly 1203# being reentered into the backups system). `cur' 1204# is created and RCS files, if necessary, are 1205# created as well. 1206# 1207# update `file' has changed and needs to be backed up. 1208# If `cur' exists, it is copied to to `back' or 1209# checked into RCS (if the repository file is old), 1210# and then `file' is copied to `cur'. Another RCS 1211# check in done here if RCS is being used. 1212# 1213# remove `file' is no longer being tracked by the backups 1214# system. If RCS is not being used, `cur' is moved 1215# to `back', otherwise an empty file is checked in, 1216# and then `cur' is removed. 1217# 1218# 1219backup_file() 1220{ 1221 _action=$1 1222 _file=$2 1223 _cur=$3 1224 _back=$4 1225 1226 if checkyesno backup_uses_rcs; then 1227 _msg0="backup archive" 1228 _msg1="update" 1229 1230 # ensure that history file is not locked 1231 if [ -f $_cur,v ]; then 1232 rcs -q -u -U -M $_cur 1233 fi 1234 1235 # ensure after switching to rcs that the 1236 # current backup is not lost 1237 if [ -f $_cur ]; then 1238 # no archive, or current newer than archive 1239 if [ ! -f $_cur,v -o $_cur -nt $_cur,v ]; then 1240 ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur 1241 rcs -q -kb -U $_cur 1242 co -q -f -u $_cur 1243 fi 1244 fi 1245 1246 case $_action in 1247 add|update) 1248 cp -p $_file $_cur 1249 ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur 1250 rcs -q -kb -U $_cur 1251 co -q -f -u $_cur 1252 chown root:wheel $_cur $_cur,v 1253 ;; 1254 remove) 1255 cp /dev/null $_cur 1256 ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur 1257 rcs -q -kb -U $_cur 1258 chown root:wheel $_cur $_cur,v 1259 rm $_cur 1260 ;; 1261 esac 1262 else 1263 case $_action in 1264 add|update) 1265 if [ -f $_cur ]; then 1266 cp -p $_cur $_back 1267 fi 1268 cp -p $_file $_cur 1269 chown root:wheel $_cur 1270 ;; 1271 remove) 1272 mv -f $_cur $_back 1273 ;; 1274 esac 1275 fi 1276} 1277 1278# make_symlink src link 1279# Make a symbolic link 'link' to src from basedir. If the 1280# directory in which link is to be created does not exist 1281# a warning will be displayed and an error will be returned. 1282# Returns 0 on success, 1 otherwise. 1283# 1284make_symlink() 1285{ 1286 local src link linkdir _me 1287 src="$1" 1288 link="$2" 1289 linkdir="`dirname $link`" 1290 _me="make_symlink()" 1291 1292 if [ -z "$src" -o -z "$link" ]; then 1293 warn "$_me: requires two arguments." 1294 return 1 1295 fi 1296 if [ ! -d "$linkdir" ]; then 1297 warn "$_me: the directory $linkdir does not exist." 1298 return 1 1299 fi 1300 if ! ln -sf $src $link; then 1301 warn "$_me: unable to make a symbolic link from $link to $src" 1302 return 1 1303 fi 1304 return 0 1305} 1306 1307# devfs_rulesets_from_file file 1308# Reads a set of devfs commands from file, and creates 1309# the specified rulesets with their rules. Returns non-zero 1310# if there was an error. 1311# 1312devfs_rulesets_from_file() 1313{ 1314 local file _err _me 1315 file="$1" 1316 _me="devfs_rulesets_from_file" 1317 _err=0 1318 1319 if [ -z "$file" ]; then 1320 warn "$_me: you must specify a file" 1321 return 1 1322 fi 1323 if [ ! -e "$file" ]; then 1324 debug "$_me: no such file ($file)" 1325 return 0 1326 fi 1327 debug "reading rulesets from file ($file)" 1328 { while read line 1329 do 1330 case $line in 1331 \#*) 1332 continue 1333 ;; 1334 \[*\]*) 1335 rulenum=`expr "$line" : "\[.*=\([0-9]*\)\]"` 1336 if [ -z "$rulenum" ]; then 1337 warn "$_me: cannot extract rule number ($line)" 1338 _err=1 1339 break 1340 fi 1341 rulename=`expr "$line" : "\[\(.*\)=[0-9]*\]"` 1342 if [ -z "$rulename" ]; then 1343 warn "$_me: cannot extract rule name ($line)" 1344 _err=1 1345 break; 1346 fi 1347 eval $rulename=\$rulenum 1348 debug "found ruleset: $rulename=$rulenum" 1349 if ! /sbin/devfs rule -s $rulenum delset; then 1350 _err=1 1351 break 1352 fi 1353 ;; 1354 *) 1355 rulecmd="${line%%"\#*"}" 1356 # evaluate the command incase it includes 1357 # other rules 1358 if [ -n "$rulecmd" ]; then 1359 debug "adding rule ($rulecmd)" 1360 if ! eval /sbin/devfs rule -s $rulenum $rulecmd 1361 then 1362 _err=1 1363 break 1364 fi 1365 fi 1366 ;; 1367 esac 1368 if [ $_err -ne 0 ]; then 1369 debug "error in $_me" 1370 break 1371 fi 1372 done } < $file 1373 return $_err 1374} 1375 1376# devfs_init_rulesets 1377# Initializes rulesets from configuration files. Returns 1378# non-zero if there was an error. 1379# 1380devfs_init_rulesets() 1381{ 1382 local file _me 1383 _me="devfs_init_rulesets" 1384 1385 # Go through this only once 1386 if [ -n "$devfs_rulesets_init" ]; then 1387 debug "$_me: devfs rulesets already initialized" 1388 return 1389 fi 1390 for file in $devfs_rulesets; do 1391 if ! devfs_rulesets_from_file $file; then 1392 warn "$_me: could not read rules from $file" 1393 return 1 1394 fi 1395 done 1396 devfs_rulesets_init=1 1397 debug "$_me: devfs rulesets initialized" 1398 return 0 1399} 1400 1401# devfs_set_ruleset ruleset [dir] 1402# Sets the default ruleset of dir to ruleset. The ruleset argument 1403# must be a ruleset name as specified in devfs.rules(5) file. 1404# Returns non-zero if it could not set it successfully. 1405# 1406devfs_set_ruleset() 1407{ 1408 local devdir rs _me 1409 [ -n "$1" ] && eval rs=\$$1 || rs= 1410 [ -n "$2" ] && devdir="-m "$2"" || devdir= 1411 _me="devfs_set_ruleset" 1412 1413 if [ -z "$rs" ]; then 1414 warn "$_me: you must specify a ruleset number" 1415 return 1 1416 fi 1417 debug "$_me: setting ruleset ($rs) on mount-point (${devdir#-m })" 1418 if ! /sbin/devfs $devdir ruleset $rs; then 1419 warn "$_me: unable to set ruleset $rs to ${devdir#-m }" 1420 return 1 1421 fi 1422 return 0 1423} 1424 1425# devfs_apply_ruleset ruleset [dir] 1426# Apply ruleset number $ruleset to the devfs mountpoint $dir. 1427# The ruleset argument must be a ruleset name as specified 1428# in a devfs.rules(5) file. Returns 0 on success or non-zero 1429# if it could not apply the ruleset. 1430# 1431devfs_apply_ruleset() 1432{ 1433 local devdir rs _me 1434 [ -n "$1" ] && eval rs=\$$1 || rs= 1435 [ -n "$2" ] && devdir="-m "$2"" || devdir= 1436 _me="devfs_apply_ruleset" 1437 1438 if [ -z "$rs" ]; then 1439 warn "$_me: you must specify a ruleset" 1440 return 1 1441 fi 1442 debug "$_me: applying ruleset ($rs) to mount-point (${devdir#-m })" 1443 if ! /sbin/devfs $devdir rule -s $rs applyset; then 1444 warn "$_me: unable to apply ruleset $rs to ${devdir#-m }" 1445 return 1 1446 fi 1447 return 0 1448} 1449 1450# devfs_domount dir [ruleset] 1451# Mount devfs on dir. If ruleset is specified it is set 1452# on the mount-point. It must also be a ruleset name as specified 1453# in a devfs.rules(5) file. Returns 0 on success. 1454# 1455devfs_domount() 1456{ 1457 local devdir rs _me 1458 devdir="$1" 1459 [ -n "$2" ] && rs=$2 || rs= 1460 _me="devfs_domount()" 1461 1462 if [ -z "$devdir" ]; then 1463 warn "$_me: you must specify a mount-point" 1464 return 1 1465 fi 1466 debug "$_me: mount-point is ($devdir), ruleset is ($rs)" 1467 if ! mount -t devfs dev "$devdir"; then 1468 warn "$_me: Unable to mount devfs on $devdir" 1469 return 1 1470 fi 1471 if [ -n "$rs" ]; then 1472 devfs_init_rulesets 1473 devfs_set_ruleset $rs $devdir 1474 devfs -m $devdir rule applyset 1475 fi 1476 return 0 1477} 1478 1479# devfs_mount_jail dir [ruleset] 1480# Mounts a devfs file system appropriate for jails 1481# on the directory dir. If ruleset is specified, the ruleset 1482# it names will be used instead. If present, ruleset must 1483# be the name of a ruleset as defined in a devfs.rules(5) file. 1484# This function returns non-zero if an error occurs. 1485# 1486devfs_mount_jail() 1487{ 1488 local jdev rs _me 1489 jdev="$1" 1490 [ -n "$2" ] && rs=$2 || rs="devfsrules_jail" 1491 _me="devfs_mount_jail" 1492 1493 devfs_init_rulesets 1494 if ! devfs_domount "$jdev" $rs; then 1495 warn "$_me: devfs was not mounted on $jdev" 1496 return 1 1497 fi 1498 return 0 1499} 1500 1501# Provide a function for normalizing the mounting of memory 1502# filesystems. This should allow the rest of the code here to remain 1503# as close as possible between 5-current and 4-stable. 1504# $1 = size 1505# $2 = mount point 1506# $3 = (optional) extra mdmfs flags 1507mount_md() 1508{ 1509 if [ -n "$3" ]; then 1510 flags="$3" 1511 fi 1512 /sbin/mdmfs $flags -s $1 md $2 1513} 1514 1515# Code common to scripts that need to load a kernel module 1516# if it isn't in the kernel yet. Syntax: 1517# load_kld [-e regex] [-m module] file 1518# where -e or -m chooses the way to check if the module 1519# is already loaded: 1520# regex is egrep'd in the output from `kldstat -v', 1521# module is passed to `kldstat -m'. 1522# The default way is as though `-m file' were specified. 1523load_kld() 1524{ 1525 local _loaded _mod _opt _re 1526 1527 while getopts "e:m:" _opt; do 1528 case "$_opt" in 1529 e) _re="$OPTARG" ;; 1530 m) _mod="$OPTARG" ;; 1531 *) err 3 'USAGE: load_kld [-e regex] [-m module] file' ;; 1532 esac 1533 done 1534 shift $(($OPTIND - 1)) 1535 if [ $# -ne 1 ]; then 1536 err 3 'USAGE: load_kld [-e regex] [-m module] file' 1537 fi 1538 _mod=${_mod:-$1} 1539 _loaded=false 1540 if [ -n "$_re" ]; then 1541 if kldstat -v | egrep -q -e "$_re"; then 1542 _loaded=true 1543 fi 1544 else 1545 if kldstat -q -m "$_mod"; then 1546 _loaded=true 1547 fi 1548 fi 1549 if ! $_loaded; then 1550 if ! kldload "$1"; then 1551 warn "Unable to load kernel module $1" 1552 return 1 1553 else 1554 info "$1 kernel module loaded." 1555 fi 1556 else 1557 debug "load_kld: $1 kernel module already loaded." 1558 fi 1559 return 0 1560} 1561 1562# ltr str src dst 1563# Change every $src in $str to $dst. 1564# Useful when /usr is not yet mounted and we cannot use tr(1), sed(1) nor 1565# awk(1). 1566ltr() 1567{ 1568 local _str _src _dst _out _com 1569 _str=$1 1570 _src=$2 1571 _dst=$3 1572 _out="" 1573 1574 IFS=${_src} 1575 for _com in ${_str}; do 1576 if [ -z "${_out}" ]; then 1577 _out="${_com}" 1578 else 1579 _out="${_out}${_dst}${_com}" 1580 fi 1581 done 1582 echo "${_out}" 1583} 1584 1585# Creates a list of providers for GELI encryption. 1586geli_make_list() 1587{ 1588 local devices devices2 1589 local provider mountpoint type options rest 1590 1591 # Create list of GELI providers from fstab. 1592 while read provider mountpoint type options rest ; do 1593 case ":${options}" in 1594 :*noauto*) 1595 noauto=yes 1596 ;; 1597 *) 1598 noauto=no 1599 ;; 1600 esac 1601 1602 case ":${provider}" in 1603 :#*) 1604 continue 1605 ;; 1606 *.eli) 1607 # Skip swap devices. 1608 if [ "${type}" = "swap" -o "${options}" = "sw" -o "${noauto}" = "yes" ]; then 1609 continue 1610 fi 1611 devices="${devices} ${provider}" 1612 ;; 1613 esac 1614 done < /etc/fstab 1615 1616 # Append providers from geli_devices. 1617 devices="${devices} ${geli_devices}" 1618 1619 for provider in ${devices}; do 1620 provider=${provider%.eli} 1621 provider=${provider#/dev/} 1622 devices2="${devices2} ${provider}" 1623 done 1624 1625 echo ${devices2} 1626} 1627 1628# Find scripts in local_startup directories that use the old syntax 1629# 1630find_local_scripts_old () { 1631 zlist='' 1632 slist='' 1633 for dir in ${local_startup}; do 1634 if [ -d "${dir}" ]; then 1635 for file in ${dir}/[0-9]*.sh; do 1636 grep '^# PROVIDE:' $file >/dev/null 2>&1 && 1637 continue 1638 zlist="$zlist $file" 1639 done 1640 for file in ${dir}/[!0-9]*.sh; do 1641 grep '^# PROVIDE:' $file >/dev/null 2>&1 && 1642 continue 1643 slist="$slist $file" 1644 done 1645 fi 1646 done 1647} 1648 1649find_local_scripts_new () { 1650 local_rc='' 1651 for dir in ${local_startup}; do 1652 if [ -d "${dir}" ]; then 1653 for file in `grep -l '^# PROVIDE:' ${dir}/* 2>/dev/null`; do 1654 case "$file" in 1655 *.sample) ;; 1656 *) if [ -x "$file" ]; then 1657 local_rc="${local_rc} ${file}" 1658 fi 1659 ;; 1660 esac 1661 done 1662 fi 1663 done 1664} 1665 1666# check_required_{before|after} command 1667# Check for things required by the command before and after its precmd, 1668# respectively. The two separate functions are needed because some 1669# conditions should prevent precmd from being run while other things 1670# depend on precmd having already been run. 1671# 1672check_required_before() 1673{ 1674 local _f 1675 1676 case "$1" in 1677 start) 1678 for _f in $required_vars; do 1679 if ! checkyesno $_f; then 1680 warn "\$${_f} is not enabled." 1681 if [ -z "$rc_force" ]; then 1682 return 1 1683 fi 1684 fi 1685 done 1686 1687 for _f in $required_dirs; do 1688 if [ ! -d "${_f}/." ]; then 1689 warn "${_f} is not a directory." 1690 if [ -z "$rc_force" ]; then 1691 return 1 1692 fi 1693 fi 1694 done 1695 1696 for _f in $required_files; do 1697 if [ ! -r "${_f}" ]; then 1698 warn "${_f} is not readable." 1699 if [ -z "$rc_force" ]; then 1700 return 1 1701 fi 1702 fi 1703 done 1704 ;; 1705 esac 1706 1707 return 0 1708} 1709 1710check_required_after() 1711{ 1712 local _f _args 1713 1714 case "$1" in 1715 start) 1716 for _f in $required_modules; do 1717 case "${_f}" in 1718 *~*) _args="-e ${_f#*~} ${_f%%~*}" ;; 1719 *:*) _args="-m ${_f#*:} ${_f%%:*}" ;; 1720 *) _args="${_f}" ;; 1721 esac 1722 if ! load_kld ${_args}; then 1723 if [ -z "$rc_force" ]; then 1724 return 1 1725 fi 1726 fi 1727 done 1728 ;; 1729 esac 1730 1731 return 0 1732} 1733 1734# check_kern_features mib 1735# Return existence of kern.features.* sysctl MIB as true or 1736# false. The result will be cached in $_rc_cache_kern_features_ 1737# namespace. "0" means the kern.features.X exists. 1738 1739check_kern_features() 1740{ 1741 local _v 1742 1743 [ -n "$1" ] || return 1; 1744 eval _v=\$_rc_cache_kern_features_$1 1745 [ -n "$_v" ] && return "$_v"; 1746 1747 if ${SYSCTL_N} kern.features.$1 > /dev/null 2>&1; then 1748 eval _rc_cache_kern_features_$1=0 1749 return 0 1750 else 1751 eval _rc_cache_kern_features_$1=1 1752 return 1 1753 fi 1754} 1755 1756# _echoonce var msg mode 1757# mode=0: Echo $msg if ${$var} is empty. 1758# After doing echo, a string is set to ${$var}. 1759# 1760# mode=1: Echo $msg if ${$var} is a string with non-zero length. 1761# 1762_echoonce() 1763{ 1764 local _var _msg _mode 1765 eval _var=\$$1 1766 _msg=$2 1767 _mode=$3 1768 1769 case $_mode in 1770 1) [ -n "$_var" ] && echo "$_msg" ;; 1771 *) [ -z "$_var" ] && echo -n "$_msg" && eval "$1=finished" ;; 1772 esac 1773} 1774 1775fi # [ -z "${_rc_subr_loaded}" ] 1776 1777_rc_subr_loaded=: 1778