rc.subr revision 160668
1139749Simp# $NetBSD: rc.subr,v 1.66 2006/04/01 10:05:50 he Exp $ 2126177Srik# $FreeBSD: head/etc/rc.subr 160668 2006-07-25 17:16:48Z yar $ 3126177Srik# 4126177Srik# Copyright (c) 1997-2004 The NetBSD Foundation, Inc. 5126177Srik# All rights reserved. 6126177Srik# 7126177Srik# This code is derived from software contributed to The NetBSD Foundation 8126177Srik# by Luke Mewburn. 9126177Srik# 10126177Srik# Redistribution and use in source and binary forms, with or without 11126177Srik# modification, are permitted provided that the following conditions 12126177Srik# are met: 13126177Srik# 1. Redistributions of source code must retain the above copyright 14126177Srik# notice, this list of conditions and the following disclaimer. 15126177Srik# 2. Redistributions in binary form must reproduce the above copyright 16126177Srik# notice, this list of conditions and the following disclaimer in the 17126177Srik# documentation and/or other materials provided with the distribution. 18126177Srik# 3. All advertising materials mentioning features or use of this software 19126177Srik# must display the following acknowledgement: 20126177Srik# This product includes software developed by the NetBSD 21126177Srik# Foundation, Inc. and its contributors. 22126177Srik# 4. Neither the name of The NetBSD Foundation nor the names of its 23126177Srik# contributors may be used to endorse or promote products derived 24126177Srik# from this software without specific prior written permission. 25126177Srik# 26126177Srik# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27126177Srik# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28126177Srik# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29126177Srik# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30126177Srik# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31126177Srik# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32126177Srik# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33126177Srik# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34126177Srik# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35126177Srik# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36126177Srik# POSSIBILITY OF SUCH DAMAGE. 37126177Srik# 38126177Srik# rc.subr 39126177Srik# functions used by various rc scripts 40126177Srik# 41126177Srik 42126177Srik: ${rcvar_manpage:='rc.conf(5)'} 43126177Srik 44126177Srik# 45126177Srik# Operating System dependent/independent variables 46126177Srik# 47126177Srik 48126177Srikif [ -z "${_rc_subr_loaded}" ]; then 49126177Srik 50126177Srik_rc_subr_loaded="YES" 51126177Srik 52126177SrikSYSCTL="/sbin/sysctl" 53126177SrikSYSCTL_N="${SYSCTL} -n" 54126177SrikCMD_OSTYPE="${SYSCTL_N} kern.ostype" 55126177SrikOSTYPE=`${CMD_OSTYPE}` 56126177SrikID="/usr/bin/id" 57126177SrikJID=`ps -p $$ -o jid=` 58126177SrikIDCMD="if [ -x $ID ]; then $ID -un; fi" 59126177Srik 60126177Srikcase ${OSTYPE} in 61126177SrikFreeBSD) 62126177Srik SYSCTL_W="${SYSCTL}" 63126177Srik ;; 64126177SrikNetBSD) 65126177Srik SYSCTL_W="${SYSCTL} -w" 66126177Srik ;; 67126177Srikesac 68126177Srik 69126177Srik# 70126177Srik# functions 71126177Srik# --------- 72126177Srik 73126177Srik# 74126177Srik# set_rcvar base_var 75126177Srik# Set the variable name enabling a specific service. 76126177Srik# FreeBSD uses ${service}_enable, while NetBSD uses 77126177Srik# just the name of the service. For example: 78126177Srik# FreeBSD: sendmail_enable="YES" 79126177Srik# NetBSD : sendmail="YES" 80126177Srik# $1 - if $name is not the base to work of off, specify 81126177Srik# a different one 82126177Srik# 83126177Srikset_rcvar() 84126177Srik{ 85126177Srik if [ -z "$1" ]; then 86126177Srik base_var=${name} 87126177Srik else 88126177Srik base_var="$1" 89126177Srik fi 90126177Srik 91126177Srik case ${OSTYPE} in 92126177Srik FreeBSD) 93126177Srik echo ${base_var}_enable 94126177Srik ;; 95126177Srik NetBSD) 96126177Srik echo ${base_var} 97126177Srik ;; 98126177Srik *) 99126177Srik echo 'XXX' 100126177Srik ;; 101126177Srik esac 102126177Srik} 103126177Srik 104126177Srik# 105126177Srik# force_depend script 106126177Srik# Force a service to start. Intended for use by services 107315221Spfg# to resolve dependency issues. It is assumed the caller 108126177Srik# has check to make sure this call is necessary 109126177Srik# $1 - filename of script, in /etc/rc.d, to run 110126177Srik# 111126177Srikforce_depend() 112126177Srik{ 113126177Srik _depend="$1" 114126177Srik 115126177Srik info "${name} depends on ${_depend}, which will be forced to start." 116126177Srik if ! /etc/rc.d/${_depend} forcestart; then 117126177Srik warn "Unable to force ${_depend}. It may already be running." 118126177Srik return 1 119126177Srik fi 120126177Srik return 0 121126177Srik} 122126177Srik 123126177Srik# 124126177Srik# checkyesno var 125126177Srik# Test $1 variable, and warn if not set to YES or NO. 126126177Srik# Return 0 if it's "yes" (et al), nonzero otherwise. 127126177Srik# 128126177Srikcheckyesno() 129126177Srik{ 130126177Srik eval _value=\$${1} 131126177Srik debug "checkyesno: $1 is set to $_value." 132126177Srik case $_value in 133126177Srik 134126177Srik # "yes", "true", "on", or "1" 135126177Srik [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 136126177Srik return 0 137126177Srik ;; 138126177Srik 139126177Srik # "no", "false", "off", or "0" 140126177Srik [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) 141126177Srik return 1 142126177Srik ;; 143126177Srik *) 144126177Srik warn "\$${1} is not set properly - see ${rcvar_manpage}." 145126177Srik return 1 146126177Srik ;; 147126177Srik esac 148126177Srik} 149126177Srik 150126177Srik# 151126177Srik# reverse_list list 152126177Srik# print the list in reverse order 153126177Srik# 154126177Srikreverse_list() 155126177Srik{ 156126177Srik _revlist= 157126177Srik for _revfile; do 158126177Srik _revlist="$_revfile $_revlist" 159126177Srik done 160126177Srik echo $_revlist 161126177Srik} 162126177Srik 163126177Srik# 164126177Srik# mount_critical_filesystems type 165126177Srik# Go through the list of critical filesystems as provided in 166126177Srik# the rc.conf(5) variable $critical_filesystems_${type}, checking 167126177Srik# each one to see if it is mounted, and if it is not, mounting it. 168126177Srik# 169126177Srikmount_critical_filesystems() 170126177Srik{ 171126177Srik eval _fslist=\$critical_filesystems_${1} 172126177Srik for _fs in $_fslist; do 173126177Srik mount | ( 174126177Srik _ismounted=false 175126177Srik while read what _on on _type type; do 176126177Srik if [ $on = $_fs ]; then 177126177Srik _ismounted=true 178126177Srik fi 179126177Srik done 180126177Srik if $_ismounted; then 181126177Srik : 182126177Srik else 183126177Srik mount $_fs >/dev/null 2>&1 184126177Srik fi 185126177Srik ) 186126177Srik done 187126177Srik} 188126177Srik 189126177Srik# 190126177Srik# check_pidfile pidfile procname [interpreter] 191126177Srik# Parses the first line of pidfile for a PID, and ensures 192126177Srik# that the process is running and matches procname. 193126177Srik# Prints the matching PID upon success, nothing otherwise. 194126177Srik# interpreter is optional; see _find_processes() for details. 195126177Srik# 196126177Srikcheck_pidfile() 197126177Srik{ 198126177Srik _pidfile=$1 199126177Srik _procname=$2 200126177Srik _interpreter=$3 201126177Srik if [ -z "$_pidfile" -o -z "$_procname" ]; then 202126177Srik err 3 'USAGE: check_pidfile pidfile procname [interpreter]' 203126177Srik fi 204126177Srik if [ ! -f $_pidfile ]; then 205126177Srik debug "pid file ($_pidfile): not readable." 206126177Srik return 207126177Srik fi 208126177Srik read _pid _junk < $_pidfile 209126177Srik if [ -z "$_pid" ]; then 210126177Srik debug "pid file ($_pidfile): no pid in file." 211126177Srik return 212126177Srik fi 213126177Srik _find_processes $_procname ${_interpreter:-.} '-p '"$_pid" 214126177Srik} 215126177Srik 216126177Srik# 217126177Srik# check_process procname [interpreter] 218126177Srik# Ensures that a process (or processes) named procname is running. 219126177Srik# Prints a list of matching PIDs. 220126177Srik# interpreter is optional; see _find_processes() for details. 221126177Srik# 222126177Srikcheck_process() 223126177Srik{ 224126177Srik _procname=$1 225126177Srik _interpreter=$2 226126177Srik if [ -z "$_procname" ]; then 227126177Srik err 3 'USAGE: check_process procname [interpreter]' 228126177Srik fi 229126177Srik _find_processes $_procname ${_interpreter:-.} '-ax' 230126177Srik} 231126177Srik 232126177Srik# 233126177Srik# _find_processes procname interpreter psargs 234126177Srik# Search for procname in the output of ps generated by psargs. 235126177Srik# Prints the PIDs of any matching processes, space separated. 236126177Srik# 237126177Srik# If interpreter == ".", check the following variations of procname 238126177Srik# against the first word of each command: 239126177Srik# procname 240126177Srik# `basename procname` 241126177Srik# `basename procname` + ":" 242126177Srik# "(" + `basename procname` + ")" 243126177Srik# "[" + `basename procname` + "]" 244126177Srik# 245126177Srik# If interpreter != ".", read the first line of procname, remove the 246126177Srik# leading #!, normalise whitespace, append procname, and attempt to 247126177Srik# match that against each command, either as is, or with extra words 248126177Srik# at the end. As an alternative, to deal with interpreted daemons 249126177Srik# using perl, the basename of the interpreter plus a colon is also 250126177Srik# tried as the prefix to procname. 251126177Srik# 252126177Srik_find_processes() 253126177Srik{ 254126177Srik if [ $# -ne 3 ]; then 255126177Srik err 3 'USAGE: _find_processes procname interpreter psargs' 256126177Srik fi 257126177Srik _procname=$1 258126177Srik _interpreter=$2 259126177Srik _psargs=$3 260126177Srik 261126177Srik _pref= 262126177Srik if [ $_interpreter != "." ]; then # an interpreted script 263126177Srik read _interp < $_procname # read interpreter name 264126177Srik _interp=${_interp#\#!} # strip #! 265126177Srik set -- $_interp 266126177Srik if [ $_interpreter != $1 ]; then 267126177Srik warn "\$command_interpreter $_interpreter != $1" 268126177Srik fi 269126177Srik _interp="$* $_procname" # cleanup spaces, add _procname 270126177Srik _interpbn=${1##*/} 271126177Srik _fp_args='_argv' 272126177Srik _fp_match='case "$_argv" in 273126177Srik ${_interp}|"${_interp} "*|"${_interpbn}: ${_procname}"*)' 274126177Srik else # a normal daemon 275126177Srik _procnamebn=${_procname##*/} 276126177Srik _fp_args='_arg0 _argv' 277126177Srik _fp_match='case "$_arg0" in 278126177Srik $_procname|$_procnamebn|${_procnamebn}:|"(${_procnamebn})"|"[${_procnamebn}]")' 279126177Srik fi 280126177Srik 281126177Srik _proccheck=' 282126177Srik ps 2>/dev/null -o "pid,jid,command" '"$_psargs"' | 283126177Srik while read _npid _jid '"$_fp_args"'; do 284126177Srik case "$_npid" in 285126177Srik PID) 286126177Srik continue;; 287126177Srik esac; '"$_fp_match"' 288126177Srik if [ "$JID" -eq "$_jid" ]; 289126177Srik then echo -n "$_pref$_npid"; 290126177Srik _pref=" "; 291126177Srik fi 292126177Srik ;; 293126177Srik esac 294126177Srik done' 295126177Srik 296126177Srik# debug "in _find_processes: proccheck is ($_proccheck)." 297126177Srik eval $_proccheck 298126177Srik} 299126177Srik 300126177Srik# 301126177Srik# wait_for_pids pid [pid ...] 302126177Srik# spins until none of the pids exist 303126177Srik# 304126177Srikwait_for_pids() 305126177Srik{ 306126177Srik _list="$@" 307126177Srik if [ -z "$_list" ]; then 308126177Srik return 309126177Srik fi 310126177Srik _prefix= 311126177Srik while true; do 312126177Srik _nlist=""; 313126177Srik for _j in $_list; do 314126177Srik if kill -0 $_j 2>/dev/null; then 315126177Srik _nlist="${_nlist}${_nlist:+ }$_j" 316126177Srik fi 317126177Srik done 318126177Srik if [ -z "$_nlist" ]; then 319126177Srik break 320126177Srik fi 321126177Srik _list=$_nlist 322126177Srik echo -n ${_prefix:-"Waiting for PIDS: "}$_list 323126177Srik _prefix=", " 324126177Srik sleep 2 325126177Srik done 326126177Srik if [ -n "$_prefix" ]; then 327126177Srik echo "." 328126177Srik fi 329126177Srik} 330126177Srik 331126177Srik# 332126177Srik# run_rc_command argument 333126177Srik# Search for argument in the list of supported commands, which is: 334126177Srik# "start stop restart rcvar status poll ${extra_commands}" 335126177Srik# If there's a match, run ${argument}_cmd or the default method 336126177Srik# (see below). 337126177Srik# 338126177Srik# If argument has a given prefix, then change the operation as follows: 339126177Srik# Prefix Operation 340126177Srik# ------ --------- 341126177Srik# fast Skip the pid check, and set rc_fast=yes 342126177Srik# force Set ${rcvar} to YES, and set rc_force=yes 343126177Srik# one Set ${rcvar} to YES 344126177Srik# 345126177Srik# The following globals are used: 346126177Srik# 347126177Srik# Name Needed Purpose 348126177Srik# ---- ------ ------- 349126177Srik# name y Name of script. 350126177Srik# 351126177Srik# command n Full path to command. 352126177Srik# Not needed if ${rc_arg}_cmd is set for 353126177Srik# each keyword. 354126177Srik# 355126177Srik# command_args n Optional args/shell directives for command. 356126177Srik# 357126177Srik# command_interpreter n If not empty, command is interpreted, so 358126177Srik# call check_{pidfile,process}() appropriately. 359126177Srik# 360126177Srik# extra_commands n List of extra commands supported. 361126177Srik# 362126177Srik# pidfile n If set, use check_pidfile $pidfile $command, 363126177Srik# otherwise use check_process $command. 364126177Srik# In either case, only check if $command is set. 365126177Srik# 366126177Srik# procname n Process name to check for instead of $command. 367126177Srik# 368126177Srik# rcvar n This is checked with checkyesno to determine 369126177Srik# if the action should be run. 370126177Srik# 371126177Srik# ${name}_program n Full path to command. 372126177Srik# Meant to be used in /etc/rc.conf to override 373126177Srik# ${command}. 374126177Srik# 375126177Srik# ${name}_chroot n Directory to chroot to before running ${command} 376126177Srik# Requires /usr to be mounted. 377126177Srik# 378126177Srik# ${name}_chdir n Directory to cd to before running ${command} 379126177Srik# (if not using ${name}_chroot). 380126177Srik# 381126177Srik# ${name}_flags n Arguments to call ${command} with. 382126177Srik# NOTE: $flags from the parent environment 383126177Srik# can be used to override this. 384126177Srik# 385126177Srik# ${name}_nice n Nice level to run ${command} at. 386126177Srik# 387126177Srik# ${name}_user n User to run ${command} as, using su(1) if not 388126177Srik# using ${name}_chroot. 389126177Srik# Requires /usr to be mounted. 390126177Srik# 391126177Srik# ${name}_group n Group to run chrooted ${command} as. 392126177Srik# Requires /usr to be mounted. 393126177Srik# 394126177Srik# ${name}_groups n Comma separated list of supplementary groups 395126177Srik# to run the chrooted ${command} with. 396126177Srik# Requires /usr to be mounted. 397126177Srik# 398126177Srik# ${rc_arg}_cmd n If set, use this as the method when invoked; 399126177Srik# Otherwise, use default command (see below) 400126177Srik# 401126177Srik# ${rc_arg}_precmd n If set, run just before performing the 402126177Srik# ${rc_arg}_cmd method in the default 403126177Srik# operation (i.e, after checking for required 404126177Srik# bits and process (non)existence). 405126177Srik# If this completes with a non-zero exit code, 406126177Srik# don't run ${rc_arg}_cmd. 407126177Srik# 408126177Srik# ${rc_arg}_postcmd n If set, run just after performing the 409126177Srik# ${rc_arg}_cmd method, if that method 410126177Srik# returned a zero exit code. 411126177Srik# 412126177Srik# required_dirs n If set, check for the existence of the given 413126177Srik# directories before running the default 414126177Srik# (re)start command. 415126177Srik# 416126177Srik# required_files n If set, check for the readability of the given 417126177Srik# files before running the default (re)start 418126177Srik# command. 419126177Srik# 420126177Srik# required_vars n If set, perform checkyesno on each of the 421126177Srik# listed variables before running the default 422126177Srik# (re)start command. 423126177Srik# 424126177Srik# Default behaviour for a given argument, if no override method is 425126177Srik# provided: 426126177Srik# 427126177Srik# Argument Default behaviour 428126177Srik# -------- ----------------- 429126177Srik# start if !running && checkyesno ${rcvar} 430126177Srik# ${command} 431126177Srik# 432126177Srik# stop if ${pidfile} 433126177Srik# rc_pid=$(check_pidfile $pidfile $command) 434126177Srik# else 435126177Srik# rc_pid=$(check_process $command) 436126177Srik# kill $sig_stop $rc_pid 437126177Srik# wait_for_pids $rc_pid 438126177Srik# ($sig_stop defaults to TERM.) 439126177Srik# 440126177Srik# reload Similar to stop, except use $sig_reload instead, 441126177Srik# and doesn't wait_for_pids. 442126177Srik# $sig_reload defaults to HUP. 443126177Srik# Note that `reload' isn't provided by default, 444126177Srik# it should be enabled via $extra_commands. 445126177Srik# 446126177Srik# restart Run `stop' then `start'. 447126177Srik# 448126177Srik# status Show if ${command} is running, etc. 449126177Srik# 450126177Srik# poll Wait for ${command} to exit. 451126177Srik# 452126177Srik# rcvar Display what rc.conf variable is used (if any). 453126177Srik# 454126177Srik# Variables available to methods, and after run_rc_command() has 455126177Srik# completed: 456126177Srik# 457126177Srik# Variable Purpose 458126177Srik# -------- ------- 459126177Srik# rc_arg Argument to command, after fast/force/one processing 460126177Srik# performed 461126177Srik# 462126177Srik# rc_flags Flags to start the default command with. 463126177Srik# Defaults to ${name}_flags, unless overridden 464126177Srik# by $flags from the environment. 465126177Srik# This variable may be changed by the precmd method. 466126177Srik# 467126177Srik# rc_pid PID of command (if appropriate) 468126177Srik# 469126177Srik# rc_fast Not empty if "fast" was provided (q.v.) 470126177Srik# 471126177Srik# rc_force Not empty if "force" was provided (q.v.) 472126177Srik# 473126177Srik# 474126177Srikrun_rc_command() 475126177Srik{ 476126177Srik _return=0 477126177Srik rc_arg=$1 478126177Srik if [ -z "$name" ]; then 479126177Srik err 3 'run_rc_command: $name is not set.' 480126177Srik fi 481126177Srik 482126177Srik # Don't repeat the first argument when passing additional command- 483126177Srik # line arguments to the command subroutines. 484126177Srik # 485126177Srik shift 1 486126177Srik rc_extra_args="$*" 487126177Srik 488126177Srik _rc_prefix= 489126177Srik case "$rc_arg" in 490126177Srik fast*) # "fast" prefix; don't check pid 491126177Srik rc_arg=${rc_arg#fast} 492126177Srik rc_fast=yes 493126177Srik ;; 494126177Srik force*) # "force prefix; always run 495126177Srik rc_force=yes 496126177Srik _rc_prefix=force 497126177Srik rc_arg=${rc_arg#${_rc_prefix}} 498126177Srik if [ -n "${rcvar}" ]; then 499126177Srik eval ${rcvar}=YES 500126177Srik fi 501126177Srik ;; 502126177Srik one*) # "one" prefix; set ${rcvar}=yes 503126177Srik _rc_prefix=one 504126177Srik rc_arg=${rc_arg#${_rc_prefix}} 505126177Srik if [ -n "${rcvar}" ]; then 506126177Srik eval ${rcvar}=YES 507126177Srik fi 508126177Srik ;; 509126177Srik esac 510126177Srik 511126177Srik _keywords="start stop restart rcvar $extra_commands" 512126177Srik rc_pid= 513126177Srik _pidcmd= 514126177Srik _procname=${procname:-${command}} 515126177Srik 516126177Srik # setup pid check command 517126177Srik if [ -n "$_procname" ]; then 518126177Srik if [ -n "$pidfile" ]; then 519126177Srik _pidcmd='rc_pid=$(check_pidfile '"$pidfile $_procname $command_interpreter"')' 520126177Srik else 521126177Srik _pidcmd='rc_pid=$(check_process '"$_procname $command_interpreter"')' 522126177Srik fi 523126177Srik if [ -n "$_pidcmd" ]; then 524126177Srik _keywords="${_keywords} status poll" 525126177Srik fi 526126177Srik fi 527126177Srik 528126177Srik if [ -z "$rc_arg" ]; then 529126177Srik rc_usage $_keywords 530126177Srik fi 531126177Srik 532126177Srik if [ -n "$flags" ]; then # allow override from environment 533126177Srik rc_flags=$flags 534126177Srik else 535126177Srik eval rc_flags=\$${name}_flags 536126177Srik fi 537126177Srik eval _chdir=\$${name}_chdir _chroot=\$${name}_chroot \ 538126177Srik _nice=\$${name}_nice _user=\$${name}_user \ 539126177Srik _group=\$${name}_group _groups=\$${name}_groups 540126177Srik 541126177Srik if [ -n "$_user" ]; then # unset $_user if running as that user 542126177Srik if [ "$_user" = "$(eval $IDCMD)" ]; then 543126177Srik unset _user 544126177Srik fi 545126177Srik fi 546126177Srik 547126177Srik # if ${rcvar} is set, and $1 is not 548126177Srik # "rcvar", then run 549126177Srik # checkyesno ${rcvar} 550126177Srik # and return if that failed 551126177Srik # 552126177Srik if [ -n "${rcvar}" -a "$rc_arg" != "rcvar" ]; then 553126177Srik if ! checkyesno ${rcvar}; then 554126177Srik return 0 555126177Srik fi 556126177Srik fi 557126177Srik 558126177Srik eval $_pidcmd # determine the pid if necessary 559126177Srik 560126177Srik for _elem in $_keywords; do 561126177Srik if [ "$_elem" != "$rc_arg" ]; then 562126177Srik continue 563126177Srik fi 564126177Srik 565126177Srik # if there's a custom ${XXX_cmd}, 566126177Srik # run that instead of the default 567126177Srik # 568126177Srik eval _cmd=\$${rc_arg}_cmd _precmd=\$${rc_arg}_precmd \ 569126177Srik _postcmd=\$${rc_arg}_postcmd 570126177Srik if [ -n "$_cmd" ]; then 571126177Srik # if the precmd failed and force 572126177Srik # isn't set, exit 573126177Srik # 574126177Srik if [ -n "$_precmd" ]; then 575126177Srik debug "run_rc_command: evaluating ${_precmd}()." 576126177Srik eval $_precmd $rc_extra_args 577126177Srik _return=$? 578126177Srik [ $_return -ne 0 ] && [ -z "$rc_force" ] && 579126177Srik return 1 580126177Srik fi 581126177Srik 582126177Srik if [ -n "$_cmd" ]; then 583126177Srik debug "run_rc_command: evaluating ${_cmd}()." 584126177Srik eval $_cmd $rc_extra_args 585126177Srik _return=$? 586126177Srik [ $_return -ne 0 ] && [ -z "$rc_force" ] && 587126177Srik return 1 588126177Srik fi 589126177Srik 590126177Srik if [ -n "$_postcmd" ]; then 591126177Srik debug "run_rc_command: evaluating ${_postcmd}()." 592126177Srik eval $_postcmd $rc_extra_args 593126177Srik _return=$? 594126177Srik fi 595126177Srik return $_return 596126177Srik fi 597126177Srik 598126177Srik case "$rc_arg" in # default operations... 599126177Srik 600126177Srik status) 601126177Srik if [ -n "$rc_pid" ]; then 602126177Srik echo "${name} is running as pid $rc_pid." 603126177Srik else 604126177Srik echo "${name} is not running." 605126177Srik return 1 606126177Srik fi 607126177Srik ;; 608126177Srik 609126177Srik start) 610126177Srik if [ -z "$rc_fast" -a -n "$rc_pid" ]; then 611126177Srik echo 1>&2 "${name} already running? (pid=$rc_pid)." 612126177Srik return 1 613126177Srik fi 614126177Srik 615126177Srik if [ ! -x ${_chroot}${command} ]; then 616126177Srik warn "run_rc_command: cannot run $command" 617126177Srik return 1 618126177Srik fi 619126177Srik 620126177Srik # check for required variables, 621126177Srik # directories, and files 622126177Srik # 623126177Srik for _f in $required_vars; do 624126177Srik if ! checkyesno $_f; then 625126177Srik warn "\$${_f} is not enabled." 626126177Srik if [ -z "$rc_force" ]; then 627126177Srik return 1 628126177Srik fi 629126177Srik fi 630126177Srik done 631126177Srik for _f in $required_dirs; do 632126177Srik if [ ! -d "${_f}/." ]; then 633126177Srik warn "${_f} is not a directory." 634126177Srik if [ -z "$rc_force" ]; then 635126177Srik return 1 636126177Srik fi 637126177Srik fi 638126177Srik done 639126177Srik for _f in $required_files; do 640126177Srik if [ ! -r "${_f}" ]; then 641126177Srik warn "${_f} is not readable." 642126177Srik if [ -z "$rc_force" ]; then 643126177Srik return 1 644126177Srik fi 645126177Srik fi 646126177Srik done 647126177Srik 648126177Srik # if the precmd failed and force 649126177Srik # isn't set, exit 650126177Srik # 651126177Srik if [ -n "${_precmd}" ]; then 652126177Srik debug "run_rc_command: evaluating ${_precmd}()." 653126177Srik eval $_precmd 654126177Srik _return=$? 655126177Srik [ $_return -ne 0 ] && [ -z "$rc_force" ] && 656126177Srik return 1 657126177Srik fi 658126177Srik 659126177Srik # setup the full command to run 660126177Srik # 661126177Srik echo "Starting ${name}." 662126177Srik if [ -n "$_chroot" ]; then 663126177Srik _doit="\ 664126177Srik${_nice:+nice -n $_nice }\ 665126177Srikchroot ${_user:+-u $_user }${_group:+-g $_group }${_groups:+-G $_groups }\ 666126177Srik$_chroot $command $rc_flags $command_args" 667126177Srik else 668126177Srik _doit="\ 669126177Srik${_chdir:+cd $_chdir; }\ 670126177Srik${_nice:+nice -n $_nice }\ 671126177Srik$command $rc_flags $command_args" 672126177Srik if [ -n "$_user" ]; then 673126177Srik _doit="su -m $_user -c 'sh -c \"$_doit\"'" 674126177Srik fi 675126177Srik fi 676126177Srik 677126177Srik # run the full command; 678126177Srik # if the cmd failed and force 679126177Srik # isn't set, exit 680126177Srik # 681126177Srik debug "run_rc_command: _doit: $_doit" 682126177Srik eval $_doit 683126177Srik _return=$? 684126177Srik [ $_return -ne 0 ] && [ -z "$rc_force" ] && return 1 685126177Srik 686126177Srik # finally, run postcmd 687126177Srik # 688126177Srik if [ -n "${_postcmd}" ]; then 689126177Srik debug "run_rc_command: evaluating ${_postcmd}()." 690126177Srik eval $_postcmd 691126177Srik fi 692126177Srik ;; 693126177Srik 694126177Srik stop) 695126177Srik if [ -z "$rc_pid" ]; then 696126177Srik [ -n "$rc_fast" ] && return 0 697126177Srik if [ -n "$pidfile" ]; then 698126177Srik echo 1>&2 \ 699126177Srik "${name} not running? (check $pidfile)." 700126177Srik else 701126177Srik echo 1>&2 "${name} not running?" 702126177Srik fi 703126177Srik return 1 704126177Srik fi 705126177Srik 706126177Srik # if the precmd failed and force 707126177Srik # isn't set, exit 708126177Srik # 709126177Srik if [ -n "$_precmd" ]; then 710126177Srik eval $_precmd 711126177Srik _return=$? 712126177Srik [ $_return -ne 0 ] && [ -z "$rc_force" ] && 713126177Srik return 1 714126177Srik fi 715126177Srik 716126177Srik # send the signal to stop 717126177Srik # 718126177Srik echo "Stopping ${name}." 719126177Srik _doit="kill -${sig_stop:-TERM} $rc_pid" 720126177Srik if [ -n "$_user" ]; then 721126177Srik _doit="su -m $_user -c 'sh -c \"$_doit\"'" 722126177Srik fi 723126177Srik 724126177Srik # if the stop cmd failed and force 725126177Srik # isn't set, exit 726126177Srik # 727126177Srik eval $_doit 728126177Srik _return=$? 729126177Srik [ $_return -ne 0 ] && [ -z "$rc_force" ] && return 1 730126177Srik 731126177Srik # wait for the command to exit, 732126177Srik # and run postcmd. 733126177Srik wait_for_pids $rc_pid 734126177Srik if [ -n "$_postcmd" ]; then 735126177Srik eval $_postcmd 736126177Srik _return=$? 737126177Srik fi 738126177Srik ;; 739126177Srik 740126177Srik reload) 741126177Srik if [ -z "$rc_pid" ]; then 742126177Srik if [ -n "$pidfile" ]; then 743126177Srik echo 1>&2 \ 744126177Srik "${name} not running? (check $pidfile)." 745126177Srik else 746126177Srik echo 1>&2 "${name} not running?" 747126177Srik fi 748126177Srik return 1 749126177Srik fi 750126177Srik echo "Reloading ${name} config files." 751126177Srik if [ -n "$_precmd" ]; then 752126177Srik eval $_precmd 753126177Srik _return=$? 754126177Srik [ $_return -ne 0 ] && [ -z "$rc_force" ] && 755126177Srik return 1 756126177Srik fi 757126177Srik _doit="kill -${sig_reload:-HUP} $rc_pid" 758126177Srik if [ -n "$_user" ]; then 759126177Srik _doit="su -m $_user -c 'sh -c \"$_doit\"'" 760126177Srik fi 761126177Srik eval $_doit 762126177Srik _return=$? 763126177Srik [ $_return -ne 0 ] && [ -z "$rc_force" ] && return 1 764126177Srik if [ -n "$_postcmd" ]; then 765126177Srik eval $_postcmd 766126177Srik _return=$? 767126177Srik fi 768126177Srik ;; 769126177Srik 770126177Srik restart) 771126177Srik if [ -n "$_precmd" ]; then 772126177Srik eval $_precmd $rc_extra_args 773126177Srik _return=$? 774126177Srik [ $_return -ne 0 ] && [ -z "$rc_force" ] && 775126177Srik return 1 776126177Srik fi 777126177Srik # prevent restart being called more 778126177Srik # than once by any given script 779126177Srik # 780126177Srik if ${_rc_restart_done:-false}; then 781126177Srik return 0 782126177Srik fi 783126177Srik _rc_restart_done=true 784126177Srik 785126177Srik # run stop in a subshell to keep variables for start 786126177Srik ( run_rc_command ${_rc_prefix}stop $rc_extra_args ) 787126177Srik run_rc_command ${_rc_prefix}start $rc_extra_args 788126177Srik 789126177Srik if [ -n "$_postcmd" ]; then 790126177Srik eval $_postcmd $rc_extra_args 791126177Srik _return=$? 792126177Srik fi 793126177Srik ;; 794126177Srik 795126177Srik poll) 796126177Srik if [ -n "$rc_pid" ]; then 797126177Srik wait_for_pids $rc_pid 798126177Srik fi 799126177Srik ;; 800126177Srik 801126177Srik rcvar) 802126177Srik echo "# $name" 803126177Srik if [ -n "$rcvar" ]; then 804126177Srik if checkyesno ${rcvar}; then 805126177Srik echo "\$${rcvar}=YES" 806126177Srik else 807126177Srik echo "\$${rcvar}=NO" 808126177Srik fi 809126177Srik fi 810126177Srik ;; 811126177Srik 812126177Srik *) 813126177Srik rc_usage $_keywords 814126177Srik ;; 815126177Srik 816126177Srik esac 817126177Srik return $_return 818126177Srik done 819126177Srik 820126177Srik echo 1>&2 "$0: unknown directive '$rc_arg'." 821126177Srik rc_usage $_keywords 822126177Srik # not reached 823126177Srik} 824126177Srik 825126177Srik# 826126177Srik# run_rc_script file arg 827126177Srik# Start the script `file' with `arg', and correctly handle the 828126177Srik# return value from the script. If `file' ends with `.sh', it's 829126177Srik# sourced into the current environment. If `file' appears to be 830126177Srik# a backup or scratch file, ignore it. Otherwise if it's 831126177Srik# executable run as a child process. 832126177Srik# 833126177Srikrun_rc_script() 834126177Srik{ 835126177Srik _file=$1 836126177Srik _arg=$2 837126177Srik if [ -z "$_file" -o -z "$_arg" ]; then 838126177Srik err 3 'USAGE: run_rc_script file arg' 839126177Srik fi 840126177Srik 841126177Srik unset name command command_args command_interpreter \ 842126177Srik extra_commands pidfile procname \ 843126177Srik rcvar required_dirs required_files required_vars 844126177Srik eval unset ${_arg}_cmd ${_arg}_precmd ${_arg}_postcmd 845126177Srik 846126177Srik case "$_file" in 847126177Srik /etc/rc.d/*.sh) # run in current shell 848126177Srik set $_arg; . $_file 849126177Srik ;; 850126177Srik *[~#]|*.OLD|*.bak|*.orig|*,v) # scratch file; skip 851126177Srik warn "Ignoring scratch file $_file" 852126177Srik ;; 853126177Srik *) # run in subshell 854126177Srik if [ -x $_file ]; then 855126177Srik if [ -n "$rc_fast_and_loose" ]; then 856126177Srik set $_arg; . $_file 857126177Srik else 858126177Srik ( trap "echo Script $_file interrupted; kill -QUIT $$" 3 859126177Srik trap "echo Script $_file interrupted; exit 1" 2 860126177Srik set $_arg; . $_file ) 861126177Srik fi 862126177Srik fi 863126177Srik ;; 864126177Srik esac 865126177Srik} 866126177Srik 867126177Srik# 868126177Srik# load_rc_config name 869126177Srik# Source in the configuration file for a given name. 870126177Srik# 871126177Srikload_rc_config() 872126177Srik{ 873126177Srik local _tmp 874126177Srik 875126177Srik _name=$1 876126177Srik if [ -z "$_name" ]; then 877126177Srik err 3 'USAGE: load_rc_config name' 878126177Srik fi 879126177Srik 880126177Srik if ${_rc_conf_loaded:-false}; then 881126177Srik : 882126177Srik else 883126177Srik if [ -r /etc/defaults/rc.conf ]; then 884126177Srik debug "Sourcing /etc/defaults/rc.conf" 885126177Srik . /etc/defaults/rc.conf 886126177Srik source_rc_confs 887126177Srik elif [ -r /etc/rc.conf ]; then 888126177Srik debug "Sourcing /etc/rc.conf (/etc/defaults/rc.conf doesn't exist)." 889126177Srik . /etc/rc.conf 890126177Srik fi 891126177Srik _rc_conf_loaded=true 892126177Srik fi 893126177Srik 894126177Srik eval _override_command=\$${name}_program 895126177Srik command=${command:+${_override_command:-$command}} 896126177Srik 897126177Srik if [ -z "${command}" ]; then 898126177Srik _tmp=`/bin/realpath $0` 899126177Srik prefix=${_tmp%/etc/rc.d/*}/ 900126177Srik else 901126177Srik prefix=${command%/*bin/*}/ 902126177Srik fi 903126177Srik if [ "${prefix}" = "/" -o "${prefix}" = "/usr/" ] ; then 904126177Srik etcdir="/etc" 905126177Srik else 906126177Srik etcdir="${prefix}etc" 907126177Srik fi 908126177Srik 909126177Srik # XXX - Deprecated 910126177Srik if [ -f /etc/rc.conf.d/${_name} -a ${etcdir} != "/etc" ]; then 911126177Srik debug "Sourcing /etc/rc.conf.d/${_name}" 912126177Srik warn "Warning: /etc/rc.conf.d/${_name} is deprecated, please use ${etcdir}/rc.conf.d/${_name} instead." 913126177Srik if [ -f ${etcdir}/rc.conf.d/${_name} ]; then 914126177Srik warn "Warning: Both /etc/rc.conf.d/${_name} and ${etcdir}/rc.conf.d/${_name} exist." 915126177Srik fi 916126177Srik . /etc/rc.conf.d/${_name} 917126177Srik fi 918126177Srik 919126177Srik if [ -f ${etcdir}/rc.conf.d/${_name} ]; then 920126177Srik debug "Sourcing ${etcdir}/rc.conf.d/${_name}" 921126177Srik . ${etcdir}/rc.conf.d/${_name} 922126177Srik fi 923126177Srik 924126177Srik # XXX - Deprecated variable name support 925126177Srik # 926126177Srik case ${OSTYPE} in 927126177Srik FreeBSD) 928126177Srik [ -n "$portmap_enable" ] && rpcbind_enable="$portmap_enable" 929126177Srik [ -n "$portmap_program" ] && rpcbind_program="$portmap_program" 930126177Srik [ -n "$portmap_flags" ] && rpcbind_flags="$portmap_flags" 931126177Srik [ -n "$single_mountd_enable" ] && mountd_enable="$single_mountd_enable" 932126177Srik [ -n "$xntpd_enable" ] && ntpd_enable="$xntpd_enable" 933126177Srik [ -n "$xntpd_program" ] && ntpd_program="$xntpd_program" 934126177Srik [ -n "$xntpd_flags" ] && ntpd_flags="$xntpd_flags" 935126177Srik [ -n "$dhcp_program" ] && dhclient_program="$dhcp_program" 936126177Srik [ -n "$dhcp_flags" ] && dhclient_flags="$dhcp_flags" 937126177Srik ;; 938126177Srik esac 939126177Srik} 940126177Srik 941126177Srik# 942126177Srik# load_rc_config_var name var 943126177Srik# Read the rc.conf(5) var for name and set in the 944126177Srik# current shell, using load_rc_config in a subshell to prevent 945126177Srik# unwanted side effects from other variable assignments. 946126177Srik# 947126177Srikload_rc_config_var() 948126177Srik{ 949126177Srik if [ $# -ne 2 ]; then 950126177Srik err 3 'USAGE: load_rc_config_var name var' 951126177Srik fi 952126177Srik eval $(eval '( 953126177Srik load_rc_config '$1' >/dev/null; 954126177Srik if [ -n "${'$2'}" -o "${'$2'-UNSET}" != "UNSET" ]; then 955126177Srik echo '$2'=\'\''${'$2'}\'\''; 956126177Srik fi 957126177Srik )' ) 958126177Srik} 959126177Srik 960126177Srik# 961126177Srik# rc_usage commands 962126177Srik# Print a usage string for $0, with `commands' being a list of 963126177Srik# valid commands. 964126177Srik# 965126177Srikrc_usage() 966126177Srik{ 967126177Srik echo -n 1>&2 "Usage: $0 [fast|force|one](" 968126177Srik 969126177Srik _sep= 970126177Srik for _elem; do 971126177Srik echo -n 1>&2 "$_sep$_elem" 972126177Srik _sep="|" 973126177Srik done 974126177Srik echo 1>&2 ")" 975126177Srik exit 1 976126177Srik} 977126177Srik 978126177Srik# 979126177Srik# err exitval message 980126177Srik# Display message to stderr and log to the syslog, and exit with exitval. 981126177Srik# 982126177Srikerr() 983126177Srik{ 984126177Srik exitval=$1 985126177Srik shift 986126177Srik 987126177Srik if [ -x /usr/bin/logger ]; then 988126177Srik logger "$0: ERROR: $*" 989126177Srik fi 990126177Srik echo 1>&2 "$0: ERROR: $*" 991126177Srik exit $exitval 992126177Srik} 993126177Srik 994126177Srik# 995126177Srik# warn message 996126177Srik# Display message to stderr and log to the syslog. 997126177Srik# 998126177Srikwarn() 999126177Srik{ 1000126177Srik if [ -x /usr/bin/logger ]; then 1001126177Srik logger "$0: WARNING: $*" 1002126177Srik fi 1003126177Srik echo 1>&2 "$0: WARNING: $*" 1004126177Srik} 1005126177Srik 1006126177Srik# 1007126177Srik# info message 1008126177Srik# Display informational message to stdout and log to syslog. 1009126177Srik# 1010126177Srikinfo() 1011126177Srik{ 1012126177Srik case ${rc_info} in 1013126177Srik [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 1014126177Srik if [ -x /usr/bin/logger ]; then 1015126177Srik logger "$0: INFO: $*" 1016126177Srik fi 1017126177Srik echo "$0: INFO: $*" 1018126177Srik ;; 1019126177Srik esac 1020126177Srik} 1021126177Srik 1022126177Srik# 1023126177Srik# debug message 1024126177Srik# If debugging is enabled in rc.conf output message to stderr. 1025126177Srik# BEWARE that you don't call any subroutine that itself calls this 1026126177Srik# function. 1027126177Srik# 1028126177Srikdebug() 1029126177Srik{ 1030126177Srik case ${rc_debug} in 1031126177Srik [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 1032126177Srik if [ -x /usr/bin/logger ]; then 1033126177Srik logger "$0: INFO: $*" 1034126177Srik fi 1035126177Srik echo 1>&2 "$0: DEBUG: $*" 1036126177Srik ;; 1037126177Srik esac 1038126177Srik} 1039126177Srik 1040126177Srik# 1041126177Srik# backup_file action file cur backup 1042126177Srik# Make a backup copy of `file' into `cur', and save the previous 1043126177Srik# version of `cur' as `backup' or use rcs for archiving. 1044126177Srik# 1045126177Srik# This routine checks the value of the backup_uses_rcs variable, 1046126177Srik# which can be either YES or NO. 1047126177Srik# 1048126177Srik# The `action' keyword can be one of the following: 1049126177Srik# 1050126177Srik# add `file' is now being backed up (and is possibly 1051126177Srik# being reentered into the backups system). `cur' 1052126177Srik# is created and RCS files, if necessary, are 1053126177Srik# created as well. 1054126177Srik# 1055126177Srik# update `file' has changed and needs to be backed up. 1056126177Srik# If `cur' exists, it is copied to to `back' or 1057126177Srik# checked into RCS (if the repository file is old), 1058126177Srik# and then `file' is copied to `cur'. Another RCS 1059126177Srik# check in done here if RCS is being used. 1060126177Srik# 1061126177Srik# remove `file' is no longer being tracked by the backups 1062126177Srik# system. If RCS is not being used, `cur' is moved 1063126177Srik# to `back', otherwise an empty file is checked in, 1064126177Srik# and then `cur' is removed. 1065126177Srik# 1066126177Srik# 1067126177Srikbackup_file() 1068126177Srik{ 1069126177Srik _action=$1 1070126177Srik _file=$2 1071126177Srik _cur=$3 1072126177Srik _back=$4 1073126177Srik 1074126177Srik if checkyesno backup_uses_rcs; then 1075126177Srik _msg0="backup archive" 1076126177Srik _msg1="update" 1077126177Srik 1078126177Srik # ensure that history file is not locked 1079126177Srik if [ -f $_cur,v ]; then 1080126177Srik rcs -q -u -U -M $_cur 1081126177Srik fi 1082126177Srik 1083126177Srik # ensure after switching to rcs that the 1084126177Srik # current backup is not lost 1085126177Srik if [ -f $_cur ]; then 1086126177Srik # no archive, or current newer than archive 1087126177Srik if [ ! -f $_cur,v -o $_cur -nt $_cur,v ]; then 1088126177Srik ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur 1089126177Srik rcs -q -kb -U $_cur 1090126177Srik co -q -f -u $_cur 1091126177Srik fi 1092126177Srik fi 1093126177Srik 1094126177Srik case $_action in 1095126177Srik add|update) 1096126177Srik cp -p $_file $_cur 1097126177Srik ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur 1098126177Srik rcs -q -kb -U $_cur 1099126177Srik co -q -f -u $_cur 1100126177Srik chown root:wheel $_cur $_cur,v 1101126177Srik ;; 1102126177Srik remove) 1103126177Srik cp /dev/null $_cur 1104126177Srik ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur 1105126177Srik rcs -q -kb -U $_cur 1106126177Srik chown root:wheel $_cur $_cur,v 1107126177Srik rm $_cur 1108126177Srik ;; 1109126177Srik esac 1110126177Srik else 1111126177Srik case $_action in 1112126177Srik add|update) 1113126177Srik if [ -f $_cur ]; then 1114126177Srik cp -p $_cur $_back 1115126177Srik fi 1116126177Srik cp -p $_file $_cur 1117126177Srik chown root:wheel $_cur 1118126177Srik ;; 1119126177Srik remove) 1120126177Srik mv -f $_cur $_back 1121126177Srik ;; 1122126177Srik esac 1123126177Srik fi 1124126177Srik} 1125126177Srik 1126126177Srik# make_symlink src link 1127126177Srik# Make a symbolic link 'link' to src from basedir. If the 1128126177Srik# directory in which link is to be created does not exist 1129126177Srik# a warning will be displayed and an error will be returned. 1130126177Srik# Returns 0 on sucess, 1 otherwise. 1131126177Srik# 1132126177Srikmake_symlink() 1133126177Srik{ 1134126177Srik local src link linkdir _me 1135126177Srik src="$1" 1136126177Srik link="$2" 1137126177Srik linkdir="`dirname $link`" 1138126177Srik _me="make_symlink()" 1139126177Srik 1140126177Srik if [ -z "$src" -o -z "$link" ]; then 1141126177Srik warn "$_me: requires two arguments." 1142126177Srik return 1 1143126177Srik fi 1144126177Srik if [ ! -d "$linkdir" ]; then 1145126177Srik warn "$_me: the directory $linkdir does not exist." 1146126177Srik return 1 1147126177Srik fi 1148126177Srik if ! ln -sf $src $link; then 1149126177Srik warn "$_me: unable to make a symbolic link from $link to $src" 1150126177Srik return 1 1151126177Srik fi 1152126177Srik return 0 1153126177Srik} 1154126177Srik 1155126177Srik# devfs_rulesets_from_file file 1156126177Srik# Reads a set of devfs commands from file, and creates 1157126177Srik# the specified rulesets with their rules. Returns non-zero 1158126177Srik# if there was an error. 1159126177Srik# 1160126177Srikdevfs_rulesets_from_file() 1161126177Srik{ 1162126177Srik local file _err _me 1163 file="$1" 1164 _me="devfs_rulesets_from_file" 1165 _err=0 1166 1167 if [ -z "$file" ]; then 1168 warn "$_me: you must specify a file" 1169 return 1 1170 fi 1171 if [ ! -e "$file" ]; then 1172 debug "$_me: no such file ($file)" 1173 return 0 1174 fi 1175 debug "reading rulesets from file ($file)" 1176 { while read line 1177 do 1178 case $line in 1179 \#*) 1180 continue 1181 ;; 1182 \[*\]*) 1183 rulenum=`expr "$line" : "\[.*=\([0-9]*\)\]"` 1184 if [ -z "$rulenum" ]; then 1185 warn "$_me: cannot extract rule number ($line)" 1186 _err=1 1187 break 1188 fi 1189 rulename=`expr "$line" : "\[\(.*\)=[0-9]*\]"` 1190 if [ -z "$rulename" ]; then 1191 warn "$_me: cannot extract rule name ($line)" 1192 _err=1 1193 break; 1194 fi 1195 eval $rulename=\$rulenum 1196 debug "found ruleset: $rulename=$rulenum" 1197 if ! /sbin/devfs rule -s $rulenum delset; then 1198 _err=1 1199 break 1200 fi 1201 ;; 1202 *) 1203 rulecmd="${line%%"\#*"}" 1204 # evaluate the command incase it includes 1205 # other rules 1206 if [ -n "$rulecmd" ]; then 1207 debug "adding rule ($rulecmd)" 1208 if ! eval /sbin/devfs rule -s $rulenum $rulecmd 1209 then 1210 _err=1 1211 break 1212 fi 1213 fi 1214 ;; 1215 esac 1216 if [ $_err -ne 0 ]; then 1217 debug "error in $_me" 1218 break 1219 fi 1220 done } < $file 1221 return $_err 1222} 1223 1224# devfs_init_rulesets 1225# Initializes rulesets from configuration files. Returns 1226# non-zero if there was an error. 1227# 1228devfs_init_rulesets() 1229{ 1230 local file _me 1231 _me="devfs_init_rulesets" 1232 1233 # Go through this only once 1234 if [ -n "$devfs_rulesets_init" ]; then 1235 debug "$_me: devfs rulesets already initialized" 1236 return 1237 fi 1238 for file in $devfs_rulesets; do 1239 devfs_rulesets_from_file $file || return 1 1240 done 1241 devfs_rulesets_init=1 1242 debug "$_me: devfs rulesets initialized" 1243 return 0 1244} 1245 1246# devfs_set_ruleset ruleset [dir] 1247# Sets the default ruleset of dir to ruleset. The ruleset argument 1248# must be a ruleset name as specified in devfs.rules(5) file. 1249# Returns non-zero if it could not set it successfully. 1250# 1251devfs_set_ruleset() 1252{ 1253 local devdir rs _me 1254 [ -n "$1" ] && eval rs=\$$1 || rs= 1255 [ -n "$2" ] && devdir="-m "$2"" || devdir= 1256 _me="devfs_set_ruleset" 1257 1258 if [ -z "$rs" ]; then 1259 warn "$_me: you must specify a ruleset number" 1260 return 1 1261 fi 1262 debug "$_me: setting ruleset ($rs) on mount-point (${devdir#-m })" 1263 if ! /sbin/devfs $devdir ruleset $rs; then 1264 warn "$_me: unable to set ruleset $rs to ${devdir#-m }" 1265 return 1 1266 fi 1267 return 0 1268} 1269 1270# devfs_apply_ruleset ruleset [dir] 1271# Apply ruleset number $ruleset to the devfs mountpoint $dir. 1272# The ruleset argument must be a ruleset name as specified 1273# in a devfs.rules(5) file. Returns 0 on success or non-zero 1274# if it could not apply the ruleset. 1275# 1276devfs_apply_ruleset() 1277{ 1278 local devdir rs _me 1279 [ -n "$1" ] && eval rs=\$$1 || rs= 1280 [ -n "$2" ] && devdir="-m "$2"" || devdir= 1281 _me="devfs_apply_ruleset" 1282 1283 if [ -z "$rs" ]; then 1284 warn "$_me: you must specify a ruleset" 1285 return 1 1286 fi 1287 debug "$_me: applying ruleset ($rs) to mount-point (${devdir#-m })" 1288 if ! /sbin/devfs $devdir rule -s $rs applyset; then 1289 warn "$_me: unable to apply ruleset $rs to ${devdir#-m }" 1290 return 1 1291 fi 1292 return 0 1293} 1294 1295# devfs_domount dir [ruleset] 1296# Mount devfs on dir. If ruleset is specified it is set 1297# on the mount-point. It must also be a ruleset name as specified 1298# in a devfs.rules(5) file. Returns 0 on success. 1299# 1300devfs_domount() 1301{ 1302 local devdir rs _me 1303 devdir="$1" 1304 [ -n "$2" ] && rs=$2 || rs= 1305 _me="devfs_domount()" 1306 1307 if [ -z "$devdir" ]; then 1308 warn "$_me: you must specify a mount-point" 1309 return 1 1310 fi 1311 debug "$_me: mount-point is ($devdir), ruleset is ($rs)" 1312 if ! mount -t devfs dev "$devdir"; then 1313 warn "$_me: Unable to mount devfs on $devdir" 1314 return 1 1315 fi 1316 if [ -n "$rs" ]; then 1317 devfs_init_rulesets 1318 devfs_set_ruleset $rs $devdir 1319 devfs -m $devdir rule applyset 1320 fi 1321 return 0 1322} 1323 1324# devfs_mount_jail dir [ruleset] 1325# Mounts a devfs file system appropriate for jails 1326# on the directory dir. If ruleset is specified, the ruleset 1327# it names will be used instead. If present, ruleset must 1328# be the name of a ruleset as defined in a devfs.rules(5) file. 1329# This function returns non-zero if an error occurs. 1330# 1331devfs_mount_jail() 1332{ 1333 local jdev rs _me 1334 jdev="$1" 1335 [ -n "$2" ] && rs=$2 || rs="devfsrules_jail" 1336 _me="devfs_mount_jail" 1337 1338 devfs_init_rulesets 1339 if ! devfs_domount "$jdev" $rs; then 1340 warn "$_me: devfs was not mounted on $jdev" 1341 return 1 1342 fi 1343 return 0 1344} 1345 1346# Provide a function for normalizing the mounting of memory 1347# filesystems. This should allow the rest of the code here to remain 1348# as close as possible between 5-current and 4-stable. 1349# $1 = size 1350# $2 = mount point 1351# $3 = (optional) extra mdmfs flags 1352mount_md() 1353{ 1354 if [ -n "$3" ]; then 1355 flags="$3" 1356 fi 1357 /sbin/mdmfs $flags -s $1 md $2 1358} 1359 1360# Code common to scripts that need to load a kernel module 1361# if it isn't in the kernel yet. Syntax: 1362# load_kld [-e regex] [-m module] file 1363# where -e or -m chooses the way to check if the module 1364# is already loaded: 1365# regex is egrep'd in the output from `kldstat -v', 1366# module is passed to `kldstat -m'. 1367# The default way is as though `-m file' were specified. 1368load_kld() 1369{ 1370 local _loaded _mod _opt _re 1371 1372 while getopts "e:m:" _opt; do 1373 case "$_opt" in 1374 e) _re="$OPTARG" ;; 1375 m) _mod="$OPTARG" ;; 1376 *) err 3 'USAGE: load_kld [-e regex] [-m module] file' ;; 1377 esac 1378 done 1379 shift $(($OPTIND - 1)) 1380 if [ $# -ne 1 ]; then 1381 err 3 'USAGE: load_kld [-e regex] [-m module] file' 1382 fi 1383 _mod=${_mod:-$1} 1384 _loaded=false 1385 if [ -n "$_re" ]; then 1386 if kldstat -v | egrep -q -e "$_re"; then 1387 _loaded=true 1388 fi 1389 else 1390 if kldstat -q -m "$_mod"; then 1391 _loaded=true 1392 fi 1393 fi 1394 if ! $_loaded; then 1395 if ! kldload "$1"; then 1396 warn "Unable to load kernel module $1" 1397 return 1 1398 else 1399 info "$1 kernel module loaded." 1400 fi 1401 else 1402 debug "load_kld: $1 kernel module already loaded." 1403 fi 1404 return 0 1405} 1406 1407# ltr str src dst 1408# Change every $src in $str to $dst. 1409# Useful when /usr is not yet mounted and we cannot use tr(1), sed(1) nor 1410# awk(1). 1411ltr() 1412{ 1413 local _str _src _dst _out _com 1414 _str=$1 1415 _src=$2 1416 _dst=$3 1417 _out="" 1418 1419 IFS=${_src} 1420 for _com in ${_str}; do 1421 if [ -z "${_out}" ]; then 1422 _out="${_com}" 1423 else 1424 _out="${_out}${_dst}${_com}" 1425 fi 1426 done 1427 echo "${_out}" 1428} 1429 1430# Creates a list of providers for GELI encryption. 1431geli_make_list() 1432{ 1433 local devices devices2 1434 local provider mountpoint type options rest 1435 1436 # Create list of GELI providers from fstab. 1437 while read provider mountpoint type options rest ; do 1438 case ":${options}" in 1439 :*noauto*) 1440 noauto=yes 1441 ;; 1442 *) 1443 noauto=no 1444 ;; 1445 esac 1446 1447 case ":${provider}" in 1448 :#*) 1449 continue 1450 ;; 1451 *.eli) 1452 # Skip swap devices. 1453 if [ "${type}" = "swap" -o "${options}" = "sw" -o "${noauto}" = "yes" ]; then 1454 continue 1455 fi 1456 devices="${devices} ${provider}" 1457 ;; 1458 esac 1459 done < /etc/fstab 1460 1461 # Append providers from geli_devices. 1462 devices="${devices} ${geli_devices}" 1463 1464 for provider in ${devices}; do 1465 provider=${provider%.eli} 1466 provider=${provider#/dev/} 1467 devices2="${devices2} ${provider}" 1468 done 1469 1470 echo ${devices2} 1471} 1472 1473# Find scripts in local_startup directories that use the old syntax 1474# 1475find_local_scripts_old () { 1476 zlist='' 1477 slist='' 1478 for dir in ${local_startup}; do 1479 if [ -d "${dir}" ]; then 1480 for file in ${dir}/[0-9]*.sh; do 1481 grep '^# PROVIDE:' $file >/dev/null 2>&1 && 1482 continue 1483 zlist="$zlist $file" 1484 done 1485 for file in ${dir}/[^0-9]*.sh; do 1486 grep '^# PROVIDE:' $file >/dev/null 2>&1 && 1487 continue 1488 slist="$slist $file" 1489 done 1490 fi 1491 done 1492} 1493 1494find_local_scripts_new () { 1495 local_rc='' 1496 for dir in ${local_startup}; do 1497 if [ -d "${dir}" ]; then 1498 for file in `grep -l '^# PROVIDE:' ${dir}/* 2>/dev/null`; do 1499 case "$file" in 1500 *.sample) ;; 1501 *) if [ -x "$file" ]; then 1502 local_rc="${local_rc} ${file}" 1503 fi 1504 ;; 1505 esac 1506 done 1507 fi 1508 done 1509} 1510 1511fi 1512 1513_rc_subr_loaded=: 1514