kernel - Refactor scheduler weightings part 2/2.
[dragonfly.git] / etc / rc.subr
1 # $NetBSD: rc.subr,v 1.49 2002/05/21 12:31:01 lukem Exp $
2 # $FreeBSD: head/etc/rc.subr 275359 2014-12-01 12:17:42Z des $
3 #
4 # Copyright (c) 1997-2002 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 # 3. All advertising materials mentioning features or use of this software
19 #    must display the following acknowledgement:
20 #        This product includes software developed by the NetBSD
21 #        Foundation, Inc. and its contributors.
22 # 4. Neither the name of The NetBSD Foundation nor the names of its
23 #    contributors may be used to endorse or promote products derived
24 #    from this software without specific prior written permission.
25 #
26 # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 # POSSIBILITY OF SUCH DAMAGE.
37 #
38 # rc.subr
39 #       functions used by various rc scripts
40 #
41
42 #
43 #       Operating System dependent/independent variables
44 #
45
46 if [ -z "$_file" ]; then
47         _file="$0"
48 fi
49 provide_list=`rcorder -p $_file`
50
51 if [ -n "${_rc_subr_loaded}" ]; then
52         return
53 fi
54
55 _rc_subr_loaded="YES"
56
57 SYSCTL="/sbin/sysctl"
58 SYSCTL_N="${SYSCTL} -n"
59 CMD_OSTYPE="${SYSCTL_N} kern.ostype"
60 OSTYPE=`${CMD_OSTYPE}`
61
62 RC_RUNNING=0
63 RC_FAILED=1
64 RC_DISABLED=2
65 RC_IRRELEVANT=3
66 RC_CONFIGURED=4
67 RC_STOPPED=5
68 SYSCTL_W="${SYSCTL}"
69
70 #
71 #       functions
72 #       ---------
73
74 # list_vars pattern
75 #       List vars matching pattern.
76 #
77 list_vars()
78 {
79         set | { while read LINE; do
80                 var="${LINE%%=*}"
81                 case "$var" in
82                 "$LINE"|*[!a-zA-Z0-9_]*) continue ;;
83                 $1) echo $var
84                 esac
85         done; }
86 }
87
88 # set_rcvar base_var
89 #       Set the variable name enabling a specific service.
90 #       FreeBSD uses ${service}_enable, while NetBSD uses
91 #       just the name of the service. For example:
92 #       FreeBSD: sendmail_enable="YES"
93 #       NetBSD : sendmail="YES"
94 #       $1 - if $name is not the base to work of off, specify
95 #            a different one
96 #
97 set_rcvar()
98 {
99         if [ -z "$1" ]; then
100                 base_var=${name}
101         else
102                 base_var="$1"
103         fi
104
105         echo ${base_var}
106 }
107
108 # set_provide_list
109 #
110 #       $1      should be $rc_arg (start, stop, restart, reload, etc)
111 #       $2      return value $RC_* 
112 #
113 #       Set the rcng_* variables associated with elements in provide_list
114 #       based on $1 and $2.
115 #
116 #       Returns non-zero when early termination should occur, in which
117 #       case the caller should return with a value of $? - 1
118 #
119 set_provide_list()
120 {
121     # Remember, plret is set to the early termination return code + 1,
122     # or 0 if we want to continue the operation.
123     #
124     for i in $provide_list; do
125         case $1$2 in
126         start$RC_RUNNING|restart$RC_RUNNING)
127             varsym -s rcng_$i=running
128             ;;
129         start$RC_FAILED|restart$RC_FAILED)
130             varsym -s rcng_$i=failed
131             ;;
132         start$RC_DISABLED|restart$RC_DISABLED|reload$RC_DISABLED)
133             varsym -s rcng_$i=disabled
134             ;;
135         start$RC_IRRELEVANT|restart$RC_IRRELEVANT|reload$RC_IRRELEVANT)
136             varsym -s rcng_$i=irrelevant
137             ;;
138         start$RC_CONFIGURED|restart$RC_CONFIGURED)
139             varsym -s rcng_$i=configured
140             ;;
141         stop$RC_DISABLED)
142             varsym -s rcng_$i=disabled
143             ;;
144         stop$RC_IRRELEVANT)
145             varsym -s rcng_$i=irrelevant
146             ;;
147         stop*)
148             varsym -s rcng_$i=stopped
149             ;;
150         *)
151             ;;
152         esac
153     done
154 }
155
156 # check_early_term
157 #       $1      should be $rc_arg (start, stop, restart, reload, etc)
158 #       $2      return value $RC_* 
159 #       $3      $rc_force       "" not to force, "anything" to force.
160 #
161 # The return code is 0 if early termination is not to occur, non-zero if
162 # it is to occur.  When early termination is to occur the caller should
163 # return check_early_term()'s return code - 1.    That is, early termination
164 # can occur with or without an error.
165 #
166 # The provide list will be adjusted when early termination occurs.
167 #
168 check_early_term()
169 {
170     case $2 in
171     $RC_RUNNING)
172         return 0
173         ;;
174     $RC_FAILED)
175         set_provide_list $1 $2
176         [ -z "$3" ] || return 0
177         return 2
178         ;;
179     $RC_DISABLED)
180         set_provide_list $1 $2
181         [ -z "$3" ] || return 0
182         return 1
183         ;;
184     $RC_IRRELEVANT)
185         set_provide_list $1 $2
186         [ -z "$3" ] || return 0
187         return 1
188         ;;
189     $RC_CONFIGURED)
190         return 0
191         ;;
192     $RC_STOPPED)
193         return 0
194         ;;
195     esac
196     set_provide_list $1 $2
197     [ -z "$3" ] || return 0
198     return 2
199 }
200
201 # adjust_return_code $1
202 #
203 #       Convert the return code to an exit code of 0 (success) or 1 (failure)
204 #
205 adjust_return_code()
206 {
207     if [ $1 = $RC_FAILED ]; then
208         return 1
209     fi
210     return 0
211 }
212
213 #
214 # force_depend script
215 #       Force a service to start. Intended for use by services
216 #       to resolve dependency issues. It is assumed the caller
217 #       has check to make sure this call is necessary
218 #       $1 - filename of script, in /etc/rc.d, to run
219 #
220 force_depend()
221 {
222         _depend="$1"
223
224         info "${name} depends on ${_depend}, which will be forced to start."
225         if ! /etc/rc.d/${_depend} forcestart ; then
226                 warn "Unable to force ${_depend}. It may already be running."
227                 return 1
228         fi
229         return 0
230 }
231
232 #
233 # checkyesno var
234 #       Test $1 variable, and warn if not set to YES or NO.
235 #       Return 0 if it's "yes" (et al), nonzero otherwise.
236 #
237 checkyesno()
238 {
239         # try foo
240         eval _value=\$${1%_enable}
241         # try foo_enable
242         if [ -z $_value ]
243         then
244                 eval _value=\$${1%_enable}_enable;
245         fi
246         debug "checkyesno: $1 is set to $_value."
247         case $_value in
248
249                 #       "yes", "true", "on", or "1"
250         [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
251                 return 0
252                 ;;
253
254                 #       "no", "false", "off", or "0"
255         [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0)
256                 return 1
257                 ;;
258         *)
259                 warn "\$${1} is not set properly - see rc.conf(5)."
260                 return 1
261                 ;;
262         esac
263 }
264
265 # reverse_list list
266 #       print the list in reverse order
267 #
268 reverse_list()
269 {
270         _revlist=
271         for _revfile in $*; do
272                 _revlist="$_revfile $_revlist"
273         done
274         echo $_revlist
275 }
276
277 #
278 # mount_critical_filesystems type
279 #       Go through the list of critical filesystems as provided in
280 #       the rc.conf(5) variable $critical_filesystems_${type}, checking
281 #       each one to see if it is mounted, and if it is not, mounting it.
282 #
283 mount_critical_filesystems()
284 {
285         eval _fslist=\$critical_filesystems_${1}
286         for _fs in $_fslist; do
287                 mount | (
288                         _ismounted=no
289                         while read what _on on _type type; do
290                                 if [ $on = $_fs ]; then
291                                         _ismounted=yes
292                                 fi
293                         done
294                         if [ $_ismounted = no ]; then
295                                 mount $_fs >/dev/null 2>&1
296                         fi
297                 )
298         done
299 }
300
301 #
302 # check_pidfile pidfile procname [interpreter]
303 #       Parses the first line of pidfile for a PID, and ensures
304 #       that the process is running and matches procname.
305 #       Prints the matching PID upon success, nothing otherwise.
306 #       interpreter is optional; see _find_processes() for details.
307 #
308 check_pidfile()
309 {
310         _pidfile=$1
311         _procname=$2
312         _interpreter=$3
313         if [ -z "$_pidfile" -o -z "$_procname" ]; then
314                 err 3 'USAGE: check_pidfile pidfile procname [interpreter]'
315         fi
316         if [ ! -f $_pidfile ]; then
317                 debug "pid file {$_pidfile): not readable."
318                 return
319         fi
320         read _pid _junk < $_pidfile
321         if [ -z "$_pid" ]; then
322                 debug "pid file {$_pidfile): no pid in file."
323                 return
324         fi
325         _find_processes $_procname ${_interpreter:-.} '-p '"$_pid"
326 }
327
328 #
329 # check_process procname [interpreter]
330 #       Ensures that a process (or processes) named procname is running.
331 #       Prints a list of matching PIDs.
332 #       interpreter is optional; see _find_processes() for details.
333 #
334 check_process()
335 {
336         _procname=$1
337         _interpreter=$2
338         if [ -z "$_procname" ]; then
339                 err 3 'USAGE: check_process procname [interpreter]'
340         fi
341         _find_processes $_procname ${_interpreter:-.} '-ax'
342 }
343
344 #
345 # _find_processes procname interpreter psargs
346 #       Search for procname in the output of ps generated by psargs.
347 #       Prints the PIDs of any matching processes, space separated.
348 #
349 #       If interpreter == ".", check the following variations of procname
350 #       against the first word of each command:
351 #               procname
352 #               `basename procname`
353 #               `basename procname` + ":"
354 #               "(" + `basename procname` + ")"
355 #
356 #       If interpreter != ".", read the first line of procname, remove the
357 #       leading #!, normalise whitespace, append procname, and attempt to
358 #       match that against each command, either as is, or with extra words
359 #       at the end.
360 #
361 _find_processes()
362 {
363         if [ $# -ne 3 ]; then
364                 err 3 'USAGE: _find_processes procname interpreter psargs'
365         fi
366         _procname=$1
367         _interpreter=$2
368         _psargs=$3
369
370         _pref=
371         if [ $_interpreter != "." ]; then       # an interpreted script
372                 read _interp < $_procname       # read interpreter name
373                 _interp=${_interp#\#!}          # strip #!
374                 set -- $_interp
375                 if [ $_interpreter != $1 ]; then
376                         warn "\$command_interpreter $_interpreter != $1"
377                 fi
378                 _interp="$* $_procname"         # cleanup spaces, add _procname
379                 _interpbn="$1"                  # the interpreter binary
380                 _fp_args='_argv'
381                 _fp_match='case "$_argv" in
382                     "${_interpbn##*/}: "$_procname*|${_interp}|"${_interp} "*)'
383         else                                    # a normal daemon
384                 _procnamebn=${_procname##*/}
385                 _fp_args='_arg0 _argv'
386                 _fp_match='case "$_arg0" in
387                     $_procname|$_procnamebn|${_procnamebn}:|"(${_procnamebn})")'
388         fi
389
390         _proccheck='
391                 ps -o "pid,command" '"$_psargs"' |
392                 while read _npid '"$_fp_args"'; do
393                         case "$_npid" in
394                             PID)
395                                 continue ;;
396                         esac ; '"$_fp_match"'
397                                 echo -n "$_pref$_npid" ;
398                                 _pref=" "
399                                 ;;
400                         esac
401                 done'
402
403 #       debug "in _find_processes: proccheck is ($_proccheck)."
404         eval $_proccheck
405 }
406
407 #
408 # wait_for_pids pid [pid ...]
409 #       spins until none of the pids exist
410 #
411 wait_for_pids()
412 {
413         _list=$*
414         if [ -z "$_list" ]; then
415                 return
416         fi
417         _prefix=
418         while true; do
419                 _nlist="";
420                 for _j in $_list; do
421                         if kill -0 $_j 2>/dev/null; then
422                                 _nlist="${_nlist}${_nlist:+ }$_j"
423                         fi
424                 done
425                 if [ -z "$_nlist" ]; then
426                         break
427                 fi
428                 _list=$_nlist
429                 echo -n ${_prefix:-"Waiting for PIDS: "}$_list
430                 _prefix=", "
431                 sleep 2
432         done
433         if [ -n "$_prefix" ]; then
434                 echo "."
435         fi
436 }
437
438 #
439 # get_pidfile_from_conf string file
440 #
441 #       Takes a string to search for in the specified file.
442 #       Ignores lines with traditional comment characters.
443 #
444 # Example:
445 #
446 # if get_pidfile_from_conf string file; then
447 #       pidfile="$_pidfile_from_conf"
448 # else
449 #       pidfile='appropriate default'
450 # fi
451 #
452 get_pidfile_from_conf()
453 {
454         if [ -z "$1" -o -z "$2" ]; then
455                 err 3 "USAGE: get_pidfile_from_conf string file ($name)"
456         fi
457
458         local string file line
459
460         string="$1" ; file="$2"
461
462         if [ ! -s "$file" ]; then
463                 err 3 "get_pidfile_from_conf: $file does not exist ($name)"
464         fi
465
466         while read line; do
467                 case "$line" in
468                 *[#\;]*${string}*)      continue ;;
469                 *${string}*)            break ;;
470                 esac
471         done < $file
472
473         if [ -n "$line" ]; then
474                 line=${line#*/}
475                 _pidfile_from_conf="/${line%%[\"\;]*}"
476         else
477                 return 1
478         fi
479 }
480
481 #
482 # check_startmsgs
483 #       If rc_quiet is set (usually as a result of using faststart at
484 #       boot time) check if rc_startmsgs is enabled.
485 #
486 check_startmsgs()
487 {
488         if [ -n "$rc_quiet" ]; then
489                 checkyesno rc_startmsgs
490         else
491                 return 0
492         fi
493 }
494
495 #
496 # run_rc_command argument
497 #       Search for argument in the list of supported commands, which is:
498 #               "start stop restart rcvar status poll ${extra_commands}"
499 #       If there's a match, run ${argument}_cmd or the default method
500 #       (see below).
501 #
502 #       If argument has a given prefix, then change the operation as follows:
503 #               Prefix  Operation
504 #               ------  ---------
505 #               fast    Skip the pid check, and set rc_fast=yes, rc_quiet=yes
506 #               force   Set ${rcvar} to YES, and set rc_force=yes
507 #               one     Set ${rcvar} to YES
508 #               quiet   Don't output some diagnostics, and set rc_quiet=yes
509 #
510 #       The following globals are used:
511 #
512 #       Name            Needed  Purpose
513 #       ----            ------  -------
514 #       provide_list    (gen)   list of keywords provided by current rcng file
515 #
516 #       name            y       Name of script.
517 #
518 #       command         n       Full path to command.
519 #                               Not needed if ${rc_arg}_cmd is set for
520 #                               each keyword.
521 #
522 #       command_args    n       Optional args/shell directives for command.
523 #
524 #       command_interpreter n   If not empty, command is interpreted, so
525 #                               call check_{pidfile,process}() appropriately.
526 #
527 #       extra_commands  n       List of extra commands supported.
528 #
529 #       pidfile         n       If set, use check_pidfile $pidfile $command,
530 #                               otherwise use check_process $command.
531 #                               In either case, only check if $command is set.
532 #
533 #       procname        n       Process name to check for instead of $command.
534 #
535 #       rcvar           n       This is checked with checkyesno to determine
536 #                               if the action should be run.
537 #
538 #       ${name}_chroot  n       Directory to chroot to before running ${command}
539 #                               Requires /usr to be mounted.
540 #
541 #       ${name}_chdir   n       Directory to cd to before running ${command}
542 #                               (if not using ${name}_chroot).
543 #
544 #       ${name}_flags   n       Arguments to call ${command} with.
545 #                               NOTE:   $flags from the parent environment
546 #                                       can be used to override this.
547 #
548 #       ${name}_env     n       Environment variables to run ${command} with.
549 #
550 #       ${name}_nice    n       Nice level to run ${command} at.
551 #
552 #       ${name}_user    n       User to run ${command} as, using su(1) if not
553 #                               using ${name}_chroot.
554 #                               Requires /usr to be mounted.
555 #
556 #       ${name}_group   n       Group to run chrooted ${command} as.
557 #                               Requires /usr to be mounted.
558 #
559 #       ${name}_groups  n       Comma separated list of supplementary groups
560 #                               to run the chrooted ${command} with.
561 #                               Requires /usr to be mounted.
562 #
563 #       ${name}_prepend n       Command added before ${command}.
564 #
565 #       ${rc_arg}_cmd   n       If set, use this as the method when invoked;
566 #                               Otherwise, use default command (see below)
567 #
568 #       ${rc_arg}_precmd n      If set, run just before performing the
569 #                               ${rc_arg}_cmd method in the default
570 #                               operation (i.e, after checking for required
571 #                               bits and process (non)existence).
572 #                               If this completes with a non-zero exit code,
573 #                               don't run ${rc_arg}_cmd.
574 #
575 #       ${rc_arg}_postcmd n     If set, run just after performing the
576 #                               ${rc_arg}_cmd method, if that method
577 #                               returned a zero exit code.
578 #
579 #       required_dirs   n       If set, check for the existence of the given
580 #                               directories before running the default
581 #                               (re)start command.
582 #
583 #       required_files  n       If set, check for the readability of the given
584 #                               files before running the default (re)start
585 #                               command.
586 #
587 #       required_modules n      If set, ensure the given kernel modules are
588 #                               loaded before running a (re)start command.
589 #                               The check and possible loads are actually
590 #                               done after start_precmd so that the modules
591 #                               aren't loaded in vain, should the precmd
592 #                               return a non-zero status to indicate a error.
593 #                               If a word in the list looks like "foo:bar",
594 #                               "foo" is the KLD file name and "bar" is the
595 #                               module name.  If a word looks like "foo~bar",
596 #                               "foo" is the KLD file name and "bar" is a
597 #                               egrep(1) pattern matching the module name.
598 #                               Otherwise the module name is assumed to be
599 #                               the same as the KLD file name, which is most
600 #                               common.  See load_kld().
601 #
602 #       required_vars   n       If set, perform checkyesno on each of the
603 #                               listed variables before running the default
604 #                               (re)start command.
605 #
606 #       Default behaviour for a given argument, if no override method is
607 #       provided:
608 #
609 #       Argument        Default behaviour
610 #       --------        -----------------
611 #       start           if !running && checkyesno ${rcvar}
612 #                               ${command}
613 #
614 #       stop            if ${pidfile}
615 #                               rc_pid=$(check_pidfile $pidfile $command)
616 #                       else
617 #                               rc_pid=$(check_process $command)
618 #                       kill $sig_stop $rc_pid
619 #                       wait_for_pids $rc_pid
620 #                       ($sig_stop defaults to TERM.)
621 #
622 #       reload          Similar to stop, except use $sig_reload instead,
623 #                       and doesn't wait_for_pids.
624 #                       $sig_reload defaults to HUP.
625 #
626 #       restart         Run `stop' then `start'.
627 #
628 #       status          Show if ${command} is running, etc.
629 #
630 #       poll            Wait for ${command} to exit.
631 #
632 #       rcvar           Display what rc.conf variable is used (if any).
633 #
634 #       Variables available to methods, and after run_rc_command() has
635 #       completed:
636 #
637 #       Variable        Purpose
638 #       --------        -------
639 #       rc_arg          Argument to command, after fast/force/one processing
640 #                       performed
641 #
642 #       rc_flags        Flags to start the default command with.
643 #                       Defaults to ${name}_flags, unless overridden
644 #                       by $flags from the environment.
645 #                       This variable may be changed by the precmd method.
646 #
647 #       rc_pid          PID of command (if appropriate)
648 #
649 #       rc_fast         Not empty if "fast" was provided (q.v.)
650 #
651 #       rc_force        Not empty if "force" was provided (q.v.)
652 #
653 #       rc_quiet        Not empty if "quiet" was provided
654 #
655 #
656 dummy_rc_command()
657 {
658         rc_arg=$1
659
660         case "$rc_arg" in
661         fast*)                          # "fast" prefix; don't check pid
662                 rc_arg=${rc_arg#fast}
663                 ;;
664         force*)                         # "force" prefix; always start
665                 rc_arg=${rc_arg#force}
666                 ;;
667         one*)                           # "one" prefix; set ${rcvar}=yes
668                 rc_arg=${rc_arg#one}
669                 ;;
670         esac
671         set_provide_list $rc_arg $RC_CONFIGURED
672         return 0
673 }
674
675 run_rc_command()
676 {
677         _return=0
678         rc_arg=$1
679         if [ -z "$name" ]; then
680                 err 3 'run_rc_command: $name is not set.'
681         fi
682
683         # Don't repeat the first argument when passing additional command-
684         # line arguments to the command subroutines.
685         #
686         shift 1
687         rc_extra_args="$*"
688
689         case "$rc_arg" in
690         fast*)                          # "fast" prefix; don't check pid
691                 rc_arg=${rc_arg#fast}
692                 rc_fast=yes
693                 rc_quiet=yes
694                 ;;
695         force*)                         # "force" prefix; always start
696                 rc_arg=${rc_arg#force}
697                 rc_force=yes
698                 if [ -n "${rcvar}" ]; then
699                         eval ${rcvar}=YES
700                 fi
701                 ;;
702         one*)                           # "one" prefix; set ${rcvar}=yes
703                 rc_arg=${rc_arg#one}
704                 if [ -n "${rcvar}" ]; then
705                         eval ${rcvar}=YES
706                 fi
707                 ;;
708         quiet*)                         # "quiet" prefix; omit some messages
709                 _rc_prefix=quiet
710                 rc_arg=${rc_arg#${_rc_prefix}}
711                 rc_quiet=yes
712                 ;;
713         esac
714
715         eval _override_command=\$${name}_program
716         if [ -n "$_override_command" ]; then
717                 command=$_override_command
718         fi
719
720         _keywords="start stop restart rcvar $extra_commands"
721         rc_pid=
722         _pidcmd=
723         _procname=${procname:-${command}}
724
725                                         # setup pid check command if not fast
726         if [ -z "$rc_fast" -a -n "$_procname" ]; then
727                 if [ -n "$pidfile" ]; then
728                         _pidcmd='rc_pid=$(check_pidfile '"$pidfile $_procname $command_interpreter"')'
729                 else
730                         _pidcmd='rc_pid=$(check_process '"$_procname $command_interpreter"')'
731                 fi
732                 if [ -n "$_pidcmd" ]; then
733                         _keywords="${_keywords} status poll"
734                 fi
735         fi
736
737         if [ -z "$rc_arg" ]; then
738                 rc_usage "$_keywords"
739         fi
740
741         if [ -n "$flags" ]; then        # allow override from environment
742                 rc_flags=$flags
743         else
744                 eval rc_flags=\$${name}_flags
745         fi
746         eval _chdir=\$${name}_chdir     _chroot=\$${name}_chroot \
747             _nice=\$${name}_nice        _user=\$${name}_user \
748             _group=\$${name}_group      _groups=\$${name}_groups \
749             _env=\$${name}_env          _prepend=\$${name}_prepend
750
751         if [ -n "$_user" ]; then        # unset $_user if running as that user
752                 if [ "$_user" = "$(id -un)" ]; then
753                         unset _user
754                 fi
755         fi
756
757                                         # if ${rcvar} is set, and $1 is not
758                                         # "rcvar", then run
759                                         #       checkyesno ${rcvar}
760                                         # and return if that failed
761                                         #
762         if [ -n "${rcvar}" -a "$rc_arg" != "rcvar" ]; then
763                 if ! checkyesno ${rcvar}; then
764                         set_provide_list $rc_arg $RC_DISABLED
765                         return 0
766                 fi
767         fi
768
769         eval $_pidcmd                   # determine the pid if necessary
770
771         for _elem in $_keywords; do
772                 if [ "$_elem" != "$rc_arg" ]; then
773                         continue
774                 fi
775
776                                         # if there's a custom ${XXX_cmd},
777                                         # run that instead of the default
778                                         #
779                 eval _cmd=\$${rc_arg}_cmd _precmd=\$${rc_arg}_precmd \
780                     _postcmd=\$${rc_arg}_postcmd
781                 if [ -n "$_cmd" ]; then
782                                         # if the precmd failed and force
783                                         # isn't set, exit
784                                         #
785                         if [ -n "$_precmd" ]; then
786                                 debug "run_rc_command: evaluating ${_precmd}()."
787                                 eval $_precmd $rc_extra_args
788
789                                 _return=$?
790                                 check_early_term $rc_arg $_return "$rc_force" || return $(($?-1))
791                         fi
792
793                         if [ -n "$_cmd" ]; then
794                                 debug "run_rc_command: evaluating ${_cmd}()."
795                                 eval $_cmd $rc_extra_args
796                                 _return=$?
797                                 check_early_term $rc_arg $_return "$rc_force" || return $(($?-1))
798                         fi
799
800                         if [ -n "$_postcmd" ]; then
801                                 debug "run_rc_command: evaluating ${_postcmd}()."
802                                 eval $_postcmd $rc_extra_args
803                                 _return=$?
804                                 check_early_term $rc_arg $_return "" || return $(($?-1))
805                         fi
806                         set_provide_list $rc_arg $_return
807                         adjust_return_code $_return
808                         return $?
809                 fi
810
811                 case "$rc_arg" in       # default operations...
812
813                 status)
814                         if [ -n "$rc_pid" ]; then
815                                 echo "${name} is running as pid $rc_pid."
816                         else
817                                 echo "${name} is not running."
818                                 return 1
819                         fi
820                         ;;
821
822                 start)
823                         if [ -n "$rc_pid" ]; then
824                                 if [ -z "$rc_quiet" ]; then
825                                         echo "${name} already running? (pid=$rc_pid)."
826                                 fi
827                                 exit 1
828                         fi
829
830                         if [ ! -x $command ]; then
831                                 info "run_rc_command: cannot run ($command)."
832                                 set_provide_list $rc_arg $RC_FAILED
833                                 adjust_return_code $RC_FAILED
834                                 return $?
835                         fi
836
837                                         # check for required variables,
838                                         # directories, and files
839                                         #
840                         for _f in $required_vars; do
841                                 if ! checkyesno $_f; then
842                                         warn "\$${_f} is not set."
843                                         if [ -z "$rc_force" ]; then
844                                                 set_provide_list $rc_arg $RC_FAILED
845                                                 adjust_return_code $RC_FAILED
846                                                 return $?
847                                         fi
848                                 fi
849                         done
850                         for _f in $required_dirs; do
851                                 if [ ! -d "${_f}/." ]; then
852                                         warn "${_f} is not a directory."
853                                         if [ -z "$rc_force" ]; then
854                                                 set_provide_list $rc_arg $RC_FAILED
855                                                 adjust_return_code $RC_FAILED
856                                                 return $?
857                                         fi
858                                 fi
859                         done
860                         for _f in $required_files; do
861                                 if [ ! -r "${_f}" ]; then
862                                         warn "${_f} is not readable."
863                                         if [ -z "$rc_force" ]; then
864                                                 set_provide_list $rc_arg $RC_FAILED
865                                                 adjust_return_code $RC_FAILED
866                                                 return $?
867                                         fi
868                                 fi
869                         done
870                         for _f in $required_modules; do
871                                 case "${_f}" in
872                                 *~*)    _args="-e ${_f#*~} ${_f%%~*}" ;;
873                                 *:*)    _args="-m ${_f#*:} ${_f%%:*}" ;;
874                                 *)      _args="${_f}" ;;
875                                 esac
876                                 if ! load_kld ${_args}; then
877                                         if [ -z "$rc_force" ]; then
878                                                 set_provide_list $rc_arg $RC_FAILED
879                                                 adjust_return_code $RC_FAILED
880                                                 return $?
881                                         fi
882                                 fi
883                         done
884
885                                         # if the precmd failed and force
886                                         # isn't set, exit
887                                         #
888                         if [ -n "${_precmd}" ]; then
889                                 debug "run_rc_command: evaluating ${_precmd}()."
890                                 eval $_precmd
891                                 _return=$?
892                                 check_early_term $rc_arg $_return "$rc_force" || return $(($?-1))
893                         fi
894
895                                         # setup the command to run, and run it
896                                         #
897                         echo "Starting ${name}."
898                         if [ -n "$_chroot" ]; then
899                                 _doit="\
900 ${_nice:+nice -n $_nice }\
901 ${_env:+env $_env }\
902 chroot ${_user:+-u $_user }${_group:+-g $_group }${_groups:+-G $_groups }\
903 $_chroot $command $rc_flags $command_args"
904                         else
905                                 _doit="\
906 ${_chdir:+cd $_chdir; }\
907 ${_nice:+nice -n $_nice }\
908 ${_env:+env $_env }\
909 $command $rc_flags $command_args"
910                                 if [ -n "$_user" ]; then
911                                     _doit="su -m $_user -c 'sh -c \"$_doit\"'"
912                                 fi
913                                 if [ -n "$_prepend" ]; then
914                                         _doit="$_prepend $_doit"
915                                 fi
916                         fi
917
918                                         # if the cmd failed and force
919                                         # isn't set, exit
920                                         #
921                         debug "run_rc_command: _doit: $_doit"
922                         eval $_doit
923                         _return=$?
924                         check_early_term $rc_arg $_return "$rc_force" || return $(($?-1))
925                                         # finally, run postcmd
926                                         #
927                         if [ -n "${_postcmd}" ]; then
928                                 debug "run_rc_command: evaluating ${_postcmd}()."
929                                 eval $_postcmd
930                         fi
931                         ;;
932
933                 stop)
934                         if [ -z "$rc_pid" ]; then
935                                 if [ -n "$pidfile" ]; then
936                                         echo \
937                                     "${name} not running? (check $pidfile)."
938                                 else
939                                         echo "${name} not running?"
940                                 fi
941                                 set_provide_list $rc_arg $RC_STOPPED
942                                 exit 1
943                         fi
944
945                                         # if the precmd failed and force
946                                         # isn't set, exit
947                                         #
948                         if [ -n "$_precmd" ]; then
949                                 eval $_precmd
950                                 _return=$?
951                                 check_early_term $rc_arg $_return "$rc_force" || return $(($?-1))
952                         fi
953
954                                         # send the signal to stop
955                                         #
956                         echo "Stopping ${name}."
957                         _doit="kill -${sig_stop:-TERM} $rc_pid"
958                         if [ -n "$_user" ]; then
959                                 _doit="su -m $_user -c 'sh -c \"$_doit\"'"
960                         fi
961
962                                         # if the stop cmd failed and force
963                                         # isn't set, exit
964                                         #
965                         eval $_doit
966                         _return=$?
967                         check_early_term $rc_arg $_return "$rc_force" || return $(($?-1))
968                                         # wait for the command to exit,
969                                         # and run postcmd.
970                         sleep 0.1
971                         wait_for_pids $rc_pid
972                         if [ -n "$_postcmd" ]; then
973                                 eval $_postcmd
974                                 _return=$?
975                         fi
976                         ;;
977
978                 reload)
979                         if [ -z "$rc_pid" ]; then
980                                 if [ -n "$pidfile" ]; then
981                                         echo \
982                                     "${name} not running? (check $pidfile)."
983                                 else
984                                         echo "${name} not running?"
985                                 fi
986                                 set_provide_list $rc_arg $RC_FAILED
987                                 exit 1
988                         fi
989                         echo "Reloading ${name} config files."
990                         if [ -n "$_precmd" ]; then
991                                 eval $_precmd
992                                 _return=$?
993                                 check_early_term $rc_arg $_return "$rc_force" || return $(($?-1))
994                         fi
995                         _doit="kill -${sig_reload:-HUP} $rc_pid"
996                         if [ -n "$_user" ]; then
997                                 _doit="su -m $_user -c 'sh -c \"$_doit\"'"
998                         fi
999                         eval $_doit
1000                         _return=$?
1001                         check_early_term $rc_arg $_return "$rc_force" || return $(($?-1))
1002                         if [ -n "$_postcmd" ]; then
1003                                 eval $_postcmd
1004                                 _return=$?
1005                         fi
1006                         ;;
1007
1008                 restart)
1009                         if [ -n "$_precmd" ]; then
1010                                 eval $_precmd $rc_extra_args
1011                                 _return=$?
1012                                 check_early_term $rc_arg $_return "$rc_force" || return $(($?-1))
1013                         fi
1014                                         # prevent restart being called more
1015                                         # than once by any given script
1016                                         #
1017                         if [ -n "$_rc_restart_done" ]; then
1018                                 return 0
1019                         fi
1020                         _rc_restart_done=YES
1021
1022                         ( $0 ${rc_force:+force}stop $rc_extra_args )
1023                         $0 ${rc_force:+force}start $rc_extra_args
1024                         _return=$?
1025
1026                         if [ -n "$_postcmd" ]; then
1027                                 eval $_postcmd $rc_extra_args
1028                                 adjust_return_code $?
1029                                 _return=$?
1030                         fi
1031                         # Do not set_provide_list(), the start command above
1032                         # will have done it for us and we do not know the
1033                         # actual RC code to base a setting on here.
1034                         #
1035                         return $_return
1036                         ;;
1037
1038                 poll)
1039                         if [ -n "$rc_pid" ]; then
1040                                 wait_for_pids $rc_pid
1041                         fi
1042                         ;;
1043
1044                 rcvar)
1045                         echo "# $name"
1046                         if [ -n "$rcvar" ]; then
1047                                 if checkyesno ${rcvar}; then
1048                                         echo "\$${rcvar}=YES"
1049                                 else
1050                                         echo "\$${rcvar}=NO"
1051                                 fi
1052                         fi
1053                         ;;
1054
1055                 *)
1056                         rc_usage "$_keywords"
1057                         ;;
1058
1059                 esac
1060                 set_provide_list $rc_arg $_return
1061                 adjust_return_code $_return
1062                 return $?
1063         done
1064
1065         echo 1>&2 "$0: unknown directive '$rc_arg'."
1066         rc_usage "$_keywords"
1067         exit 1
1068 }
1069
1070 #
1071 # Helper functions for run_rc_command: common code.
1072 # They use such global variables besides the exported rc_* ones:
1073 #
1074 #       name           R/W
1075 #       ------------------
1076 #       _precmd         R
1077 #       _postcmd        R
1078 #       _return         W
1079 #
1080 _run_rc_precmd()
1081 {
1082         check_required_before "$rc_arg" || return 1
1083
1084         if [ -n "$_precmd" ]; then
1085                 debug "run_rc_command: ${rc_arg}_precmd: $_precmd $rc_extra_args"
1086                 eval "$_precmd $rc_extra_args"
1087                 _return=$?
1088
1089                 # If precmd failed and force isn't set, request exit.
1090                 if [ $_return -ne 0 ] && [ -z "$rc_force" ]; then
1091                         return 1
1092                 fi
1093         fi
1094
1095         check_required_after "$rc_arg" || return 1
1096
1097         return 0
1098 }
1099
1100 _run_rc_postcmd()
1101 {
1102         if [ -n "$_postcmd" ]; then
1103                 debug "run_rc_command: ${rc_arg}_postcmd: $_postcmd $rc_extra_args"
1104                 eval "$_postcmd $rc_extra_args"
1105                 _return=$?
1106         fi
1107         return 0
1108 }
1109
1110 _run_rc_doit()
1111 {
1112         debug "run_rc_command: doit: $*"
1113         eval "$@"
1114         _return=$?
1115
1116         # If command failed and force isn't set, request exit.
1117         if [ $_return -ne 0 ] && [ -z "$rc_force" ]; then
1118                 return 1
1119         fi
1120
1121         return 0
1122 }
1123
1124 _run_rc_notrunning()
1125 {
1126         local _pidmsg
1127
1128         if [ -n "$pidfile" ]; then
1129                 _pidmsg=" (check $pidfile)."
1130         else
1131                 _pidmsg=
1132         fi
1133         echo 1>&2 "${name} not running?${_pidmsg}"
1134 }
1135
1136 _run_rc_killcmd()
1137 {
1138         local _cmd
1139
1140         _cmd="kill -$1 $rc_pid"
1141         if [ -n "$_user" ]; then
1142                 _cmd="su -m ${_user} -c 'sh -c \"${_cmd}\"'"
1143         fi
1144         echo "$_cmd"
1145 }
1146
1147 #
1148 # run_rc_script file arg
1149 #       Start the script `file' with `arg', and correctly handle the
1150 #       return value from the script.  If `file' ends with `.sh', it's
1151 #       sourced into the current environment.  If `file' appears to be
1152 #       a backup or scratch file, ignore it.  Otherwise if it's
1153 #       executable run as a child process.
1154 #
1155 run_rc_script()
1156 {
1157         _file=$1
1158         _arg=$2
1159         if [ -z "$_file" -o -z "$_arg" ]; then
1160                 err 3 'USAGE: run_rc_script file arg'
1161         fi
1162
1163         trap "echo 'Reboot interrupted'; exit 1" 3
1164
1165         unset   name command command_args command_interpreter \
1166                 extra_commands pidfile procname \
1167                 rcvar required_dirs required_files required_vars
1168         eval unset ${_arg}_cmd ${_arg}_precmd ${_arg}_postcmd
1169
1170         case "$_file" in
1171         *.sh)                           # run in current shell
1172                 set $_arg ; . $_file
1173                 ;;
1174         *[~#]|*.OLD|*.orig)             # scratch file; skip
1175                 warn "Ignoring scratch file $_file"
1176                 ;;
1177         *)                              # run in subshell
1178                 if [ -x $_file ]; then
1179                         if [ -n "$rc_fast_and_loose" ]; then
1180                                 set $_arg ; . $_file
1181                         else
1182                                 ( trap "echo 'Reboot interrupted'; exit 1" 3
1183                                   set $_arg ; . $_file )
1184                         fi
1185                 fi
1186                 ;;
1187         esac
1188 }
1189
1190 # Code common to scripts that need to load a kernel module
1191 # if it isn't in the kernel yet. Syntax:
1192 #   load_kld [-e regex] [-m module] file
1193 # where -e or -m chooses the way to check if the module
1194 # is already loaded:
1195 #   regex is egrep'd in the output from `kldstat -v',
1196 #   module is passed to `kldstat -m'.
1197 # The default way is as though `-m file' were specified.
1198 load_kld()
1199 {
1200         local _loaded _mod _opt _re
1201
1202         while getopts "e:m:" _opt; do
1203                 case "$_opt" in
1204                 e) _re="$OPTARG" ;;
1205                 m) _mod="$OPTARG" ;;
1206                 *) err 3 'USAGE: load_kld [-e regex] [-m module] file' ;;
1207                 esac
1208         done
1209         shift $(($OPTIND - 1))
1210         if [ $# -ne 1 ]; then
1211                 err 3 'USAGE: load_kld [-e regex] [-m module] file'
1212         fi
1213         _mod=${_mod:-$1}
1214         _loaded=false
1215         if [ -n "$_re" ]; then
1216                 if kldstat -v | egrep -q -e "$_re"; then
1217                         _loaded=true
1218                 fi
1219         else
1220                 if kldstat -q -m "$_mod"; then
1221                         _loaded=true
1222                 fi
1223         fi
1224         if ! $_loaded; then
1225                 if ! kldload "$1"; then
1226                         warn "Unable to load kernel module $1"
1227                         return 1
1228                 else
1229                         info "$1 kernel module loaded."
1230                 fi
1231         else
1232                 debug "load_kld: $1 kernel module already loaded."
1233         fi
1234         return 0
1235 }
1236
1237
1238 # ltr str src dst
1239 #       Change every $src in $str to $dst.
1240 #       Useful when /usr is not yet mounted and we cannot use tr(1), sed(1) nor
1241 #       awk(1).
1242 ltr()
1243 {
1244         local _str _src _dst _out _com
1245         _str=$1
1246         _src=$2
1247         _dst=$3
1248         _out=""
1249
1250         IFS=${_src}
1251         for _com in ${_str}; do
1252                 if [ -z "${_out}" ]; then
1253                         _out="${_com}"
1254                 else
1255                         _out="${_out}${_dst}${_com}"
1256                 fi
1257         done
1258         echo "${_out}"
1259 }
1260
1261 #
1262 # load_rc_config
1263 #       Source in the configuration file for a given command.
1264 #
1265 load_rc_config()
1266 {
1267         _command=$1
1268         if [ -z "$_command" ]; then
1269                 err 3 'USAGE: load_rc_config command'
1270         fi
1271
1272         if [ -z "$_rc_conf_loaded" ]; then
1273                 if [ -r /etc/defaults/rc.conf ]; then
1274                         debug "Sourcing /etc/defaults/rc.conf"
1275                         . /etc/defaults/rc.conf
1276                         source_rc_confs
1277                 elif [ -r /etc/rc.conf ]; then
1278                         debug "Sourcing /etc/rc.conf (/etc/defaults/rc.conf doesn't exist)."
1279                         . /etc/rc.conf
1280                 fi
1281                 _rc_conf_loaded=YES
1282         fi
1283         if [ -f /etc/rc.conf.d/"$_command" ]; then
1284                 debug "Sourcing /etc/rc.conf.d/${_command}"
1285                 . /etc/rc.conf.d/"$_command"
1286         fi
1287
1288         # XXX - Deprecated variable name support
1289         #
1290         [ -n "$portmap_enable" ] && rpcbind_enable="$portmap_enable"
1291         [ -n "$portmap_program" ] && rpcbind_program="$portmap_program"
1292         [ -n "$portmap_flags" ] && rpcbind_flags="$portmap_flags"
1293         [ -n "$single_mountd_enable" ] && mountd_enable="$single_mountd_enable"
1294
1295 }
1296
1297 #
1298 # rc_usage commands
1299 #       Print a usage string for $0, with `commands' being a list of
1300 #       valid commands.
1301 #
1302 rc_usage()
1303 {
1304         echo -n 1>&2 "Usage: $0 [fast|force|one|quiet]("
1305
1306         _sep=
1307         for _elem in $*; do
1308                 echo -n 1>&2 "$_sep$_elem"
1309                 _sep="|"
1310         done
1311         echo 1>&2 ")"
1312         exit 1
1313 }
1314
1315 #
1316 # err exitval message
1317 #       Display message to stderr and log to the syslog, and exit with exitval.
1318 #
1319 err()
1320 {
1321         exitval=$1
1322         shift
1323
1324         if [ -x /usr/bin/logger ]; then
1325                 logger "$0: ERROR: $*"
1326         fi
1327         echo 1>&2 "$0: ERROR: $*"
1328         exit $exitval
1329 }
1330
1331 #
1332 # warn message
1333 #       Display message to stderr and log to the syslog.
1334 #
1335 warn()
1336 {
1337         if [ -x /usr/bin/logger ]; then
1338                 logger "$0: WARNING: $*"
1339         fi
1340         echo 1>&2 "$0: WARNING: $*"
1341 }
1342
1343 #
1344 # info message
1345 #       Display informational message to stdout and log to syslog.
1346 #
1347 info()
1348 {
1349         case ${rc_info} in
1350         [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
1351                 if [ -x /usr/bin/logger ]; then
1352                         logger "$0: INFO: $*"
1353                 fi
1354                 echo "$0: INFO: $*"
1355                 ;;
1356         esac
1357 }
1358
1359 #
1360 # debug message
1361 #       If debugging is enabled in rc.conf output message to stderr.
1362 #       BEWARE that you don't call any subroutine that itself calls this
1363 #       function.
1364 #
1365 debug()
1366 {
1367         case ${rc_debug} in
1368         [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
1369                 if [ -x /usr/bin/logger ]; then
1370                         logger "$0: INFO: $*"
1371                 fi
1372                 echo 1>&2 "$0: DEBUG: $*"
1373                 ;;
1374         esac
1375 }
1376
1377 #
1378 # backup_file action file cur backup
1379 #       Make a backup copy of `file' into `cur', and save the previous
1380 #       version of `cur' as `backup' or use rcs for archiving.
1381 #
1382 #       This routine checks the value of the backup_uses_rcs variable,
1383 #       which can be either YES or NO.
1384 #
1385 #       The `action' keyword can be one of the following:
1386 #
1387 #       add             `file' is now being backed up (and is possibly
1388 #                       being reentered into the backups system).  `cur'
1389 #                       is created and RCS files, if necessary, are
1390 #                       created as well.
1391 #
1392 #       update          `file' has changed and needs to be backed up.
1393 #                       If `cur' exists, it is copied to to `back' or
1394 #                       checked into RCS (if the repository file is old),
1395 #                       and then `file' is copied to `cur'.  Another RCS
1396 #                       check in done here if RCS is being used.
1397 #
1398 #       remove          `file' is no longer being tracked by the backups
1399 #                       system.  If RCS is not being used, `cur' is moved
1400 #                       to `back', otherwise an empty file is checked in,
1401 #                       and then `cur' is removed.
1402 #
1403 #
1404 backup_file()
1405 {
1406         _action=$1
1407         _cpfile=$2
1408         _cur=$3
1409         _back=$4
1410
1411         if checkyesno backup_uses_rcs; then
1412                 _msg0="backup archive"
1413                 _msg1="update"
1414
1415                 # ensure that history file is not locked
1416                 if [ -f $_cur,v ]; then
1417                         rcs -q -u -U -M $_cur
1418                 fi
1419
1420                 # ensure after switching to rcs that the
1421                 # current backup is not lost
1422                 if [ -f $_cur ]; then
1423                         # no archive, or current newer than archive
1424                         if [ ! -f $_cur,v -o $_cur -nt $_cur,v ]; then
1425                                 ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur
1426                                 rcs -q -kb -U $_cur
1427                                 co -q -f -u $_cur
1428                         fi
1429                 fi
1430
1431                 case $_action in
1432                 add|update)
1433                         cp -p $_cpfile $_cur
1434                         ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur
1435                         rcs -q -kb -U $_cur
1436                         co -q -f -u $_cur
1437                         chown root:wheel $_cur $_cur,v
1438                         ;;
1439                 remove)
1440                         cp /dev/null $_cur
1441                         ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur
1442                         rcs -q -kb -U $_cur
1443                         chown root:wheel $_cur $_cur,v
1444                         rm $_cur
1445                         ;;
1446                 esac
1447         else
1448                 case $_action in
1449                 add|update)
1450                         if [ -f $_cur ]; then
1451                                 cp -p $_cur $_back
1452                         fi
1453                         cp -p $_cpfile $_cur
1454                         chown root:wheel $_cur
1455                         ;;
1456                 remove)
1457                         mv -f $_cur $_back
1458                         ;;
1459                 esac
1460         fi
1461 }
1462
1463 # devfs_mount_jail dir
1464 # Mounts a devfs file system appropriate for jails
1465 # on the directory dir.
1466 # This function returns non-zero if an error occurs.
1467 #
1468 devfs_mount_jail()
1469 {
1470         local jdev _me
1471         jdev="$1"
1472         _me="devfs_mount_jail"
1473
1474         if ! devfs_domount "$jdev" $rs; then
1475                 warn "$_me: devfs was not mounted on $jdev"
1476                 return 1
1477         fi
1478         return 0
1479 }
1480
1481 # devfs_domount dir
1482 # Mount devfs on dir.
1483 # Returns 0 on success.
1484 #
1485 devfs_domount()
1486 {
1487         local devdir _me
1488         devdir="$1"
1489         _me="devfs_domount()"
1490
1491         if [ -z "$devdir" ]; then
1492                 warn "$_me: you must specify a mount-point"
1493                 return 1
1494         fi
1495
1496         debug "$_me: mount-point is ($devdir)"
1497         if ! mount -t devfs devfs "$devdir"; then
1498                 warn "$_me: Unable to mount devfs on $devdir"
1499                 return 1
1500         fi
1501
1502 return 0
1503 }
1504
1505 # Find scripts in local_startup directories.
1506 find_local_scripts() {
1507         local_rc=''
1508         for dir in ${local_startup}; do
1509                 if [ -d "${dir}" ]; then
1510                         for file in `grep -l '^# PROVIDE:' ${dir}/* 2>/dev/null`; do
1511                                 case "$file" in
1512                                 *.sample) ;;
1513                                 *)      if [ -x "$file" ]; then
1514                                                 local_rc="${local_rc} ${file}"
1515                                         fi
1516                                         ;;
1517                                 esac
1518                         done
1519                 fi
1520         done
1521 }