[BACK]Return to rc.subr CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / etc

Annotation of src/etc/rc.subr, Revision 1.23

1.23    ! lukem       1: # $NetBSD: rc.subr,v 1.22 2000/08/17 11:07:10 lukem Exp $
1.11      lukem       2: #
                      3: # Copyright (c) 1997-2000 The NetBSD Foundation, Inc.
                      4: # All rights reserved.
                      5: #
                      6: # This code is derived from software contributed to The NetBSD Foundation
                      7: # by Luke Mewburn.
                      8: #
                      9: # Redistribution and use in source and binary forms, with or without
                     10: # modification, are permitted provided that the following conditions
                     11: # are met:
                     12: # 1. Redistributions of source code must retain the above copyright
                     13: #    notice, this list of conditions and the following disclaimer.
                     14: # 2. Redistributions in binary form must reproduce the above copyright
                     15: #    notice, this list of conditions and the following disclaimer in the
                     16: #    documentation and/or other materials provided with the distribution.
                     17: # 3. All advertising materials mentioning features or use of this software
                     18: #    must display the following acknowledgement:
                     19: #        This product includes software developed by the NetBSD
                     20: #        Foundation, Inc. and its contributors.
                     21: # 4. Neither the name of The NetBSD Foundation nor the names of its
                     22: #    contributors may be used to endorse or promote products derived
                     23: #    from this software without specific prior written permission.
                     24: #
                     25: # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     26: # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     27: # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     28: # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     29: # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     30: # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     31: # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     32: # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     33: # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     34: # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     35: # POSSIBILITY OF SUCH DAMAGE.
                     36: #
                     37: # rc.subr
                     38: #      functions used by various rc scripts
                     39: #
                     40:
                     41: #
                     42: #      functions
                     43: #      ---------
1.1       cjs        44:
1.5       lukem      45: #
1.11      lukem      46: # checkyesno var
1.5       lukem      47: #      Test $1 variable, and warn if not set to YES or NO.
1.11      lukem      48: #      Return 0 if it's "yes" (et al), nonzero otherwise.
1.5       lukem      49: #
1.11      lukem      50: checkyesno()
                     51: {
                     52:        eval _value=\$${1}
                     53:        case $_value in
1.4       lukem      54:
                     55:                #       "yes", "true", "on", or "1"
                     56:        [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
                     57:                return 0
1.3       lukem      58:                ;;
1.4       lukem      59:
                     60:                #       "no", "false", "off", or "0"
                     61:        [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0)
                     62:                return 1
1.3       lukem      63:                ;;
                     64:        *)
1.11      lukem      65:                warn "\$${1} is not set properly."
1.4       lukem      66:                return 1
1.3       lukem      67:                ;;
                     68:        esac
1.6       mellon     69: }
                     70:
                     71: #
                     72: # mount_critical_filesystems
                     73: #      Go through the list of critical filesystems, checking each one
                     74: #      to see if it is mounted, and if it is not, mounting it.
                     75: #
1.11      lukem      76: mount_critical_filesystems()
                     77: {
1.10      drochner   78:        if [ $1 = local ]; then
                     79:                _fslist=$critical_filesystems_beforenet
                     80:        else
                     81:                _fslist=$critical_filesystems
                     82:        fi
1.17      lukem      83:        for _fs in $_fslist; do
1.6       mellon     84:                mount | (
1.17      lukem      85:                        _ismounted=no
1.6       mellon     86:                        while read what _on on _type type; do
1.17      lukem      87:                                if [ $on = $_fs ]; then
                     88:                                        _ismounted=yes
1.6       mellon     89:                                fi
                     90:                        done
1.17      lukem      91:                        if [ $_ismounted = no ]; then
                     92:                                mount $_fs >/dev/null 2>&1
1.6       mellon     93:                        fi
                     94:                )
                     95:        done
1.7       cjs        96: }
                     97:
1.11      lukem      98: #
                     99: # check_pidfile pidfile procname
                    100: #      Parses the first line of pidfile for a pid, and ensures
                    101: #      that the process is running and matches procname.
                    102: #      Prints the matching pid upon success, nothing otherwise.
                    103: #
                    104: check_pidfile()
                    105: {
                    106:        _pidfile=$1
                    107:        _procname=$2
                    108:        if [ -z "$_pidfile" -o -z "$_procname" ]; then
                    109:                err 3 'USAGE: check_pidfile pidfile procname'
                    110:        fi
                    111:        if [ ! -f $_pidfile ]; then
                    112:                return
                    113:        fi
                    114:        read _pid _junk < $_pidfile
                    115:        if [ -z "$_pid" ]; then
                    116:                return
                    117:        fi
                    118:        _procnamebn=`basename $_procname`
                    119:        ps -p $_pid -o 'pid,command' | while read _npid _arg0 _argv; do
                    120:                if [ "$_npid" = "PID" ]; then
                    121:                        continue
                    122:                fi
1.15      lukem     123:                if [   "$_arg0" = "$_procname" \
                    124:                    -o "$_arg0" = "$_procnamebn" \
                    125:                    -o "$_arg0" = "${_procnamebn}:" \
                    126:                    -o "$_arg0" = "(${_procnamebn})" ]; then
1.11      lukem     127:                        echo $_npid
                    128:                        return
                    129:                fi
                    130:        done
                    131: }
                    132:
                    133: #
                    134: # check_process procname
                    135: #      Ensures that a process (or processes) named procname is running.
                    136: #      Prints a list of matching pids.
                    137: #
                    138: check_process()
                    139: {
                    140:        _procname=$1
                    141:        if [ -z "$_procname" ]; then
                    142:                err 3 'USAGE: check_process procname'
                    143:        fi
                    144:        _procnamebn=`basename $_procname`
                    145:        _pref=
                    146:        ps -ax -o 'pid,command' | while read _npid _arg0 _argv; do
                    147:                if [ "$_npid" = "PID" ]; then
                    148:                        continue
                    149:                fi
1.15      lukem     150:                if [   "$_arg0" = "$_procname" \
                    151:                    -o "$_arg0" = "$_procnamebn" \
                    152:                    -o "$_arg0" = "${_procnamebn}:" \
                    153:                    -o "$_arg0" = "(${_procnamebn})" ]; then
1.11      lukem     154:                        echo -n "$_pref$_npid"
                    155:                        _pref=" "
                    156:                fi
                    157:        done
                    158: }
                    159:
                    160: #
1.16      lukem     161: # run_rc_command arg
                    162: #      Search for arg in the list of supported commands, which is:
                    163: #              "start stop restart rcvar status ${extra_commands}"
1.11      lukem     164: #      If there's a match, run ${arg}_cmd or the default command (see below).
                    165: #
1.16      lukem     166: #      If arg has a given prefix, then change the operation as follows:
1.11      lukem     167: #              prefix  operation
                    168: #              ------  ---------
                    169: #              fast    Skip the pid check.
                    170: #              force   Set ${rcvar} to YES.
                    171: #
                    172: #      The following globals are used:
                    173: #      name            needed  function
                    174: #      ----            ------  --------
                    175: #      name            y       Name of script.
                    176: #      command         n       Full path to command.
                    177: #                              Not needed if ${arg}_cmd is set for
                    178: #                              each keyword.
                    179: #      command_args    n       Optional args/shell directives for command.
1.16      lukem     180: #      extra_commands  n       List of extra commands supported.
1.11      lukem     181: #      pidfile         n       If set, use check_pidfile $pidfile, else if
                    182: #                              $command is set, use check_process $command.
1.16      lukem     183: #      rcvar           n       If the default command is being run, this is
1.11      lukem     184: #                              checked with checkyesno to determine if
                    185: #                              the action should be run.
                    186: #                              If this variable isn't set, ${name} is checked
                    187: #                              instead.
1.22      lukem     188: #      ${name}_chroot  n       Directory to chroot to before running ${command}
                    189: #      ${name}_chdir   n       Directory to cd to before running ${command}
                    190: #                              (if not using ${name}_chroot).
1.11      lukem     191: #      ${name}_flags   n       Arguments to call ${command} with.
                    192: #                              NOTE:   if $flags is set (e.g, from the parent
                    193: #                                      environment), it overrides this.
1.23    ! lukem     194: #      ${name}_nice    n       Nice level to run ${command} at.
1.22      lukem     195: #      ${name}_user    n       User to run ${command} as, using su(1) if not
                    196: #                              using ${name}_chroot.
                    197: #      ${name}_group   n       Group to run chrooted ${command} as.
                    198: #      ${name}_groups  n       Group list to run chrooted ${command} with.
1.11      lukem     199: #      ${_arg}_cmd     n       If set, use this as the action when invoked;
                    200: #                              $_arg is available to the action to use.
                    201: #                              Otherwise, use default command (see below)
                    202: #                              NOTE:   checkyesno ${rcvar} is NOT performed
                    203: #                                      for ${_arg}_cmd; use ${_arg}_precmd to
                    204: #                                      do this.
                    205: #      ${_arg}_precmd  n       If set, run just before performing the main
                    206: #                              action in the default command (i.e, after
                    207: #                              checking for required bits and process
                    208: #                              (non)existance).
                    209: #                              If this completes with a non-zero exit code,
                    210: #                              don't run ${_arg}_cmd.
                    211: #      required_dirs   n       If set, check for the existence of the given
                    212: #                              directories before running the default
                    213: #                              (re)start command.
                    214: #      required_files  n       If set, check for the readability of the given
                    215: #                              files before running the default (re)start
                    216: #                              command.
                    217: #      required_vars   n       If set, perform checkyesno on each of the
                    218: #                              listed variables before running the default
                    219: #                              (re)start command.
                    220: #
                    221: #      Default commands for a given arg:
                    222: #      arg             default
                    223: #      ---             -------
                    224: #      status          Show if ${command} is running, etc.
                    225: #      start           if !running && checkyesno ${rcvar}
                    226: #                              ${command}
                    227: #      stop            if ${pidfile}
                    228: #                              kill $sig_stop `check_pidfile $pidfile`
                    229: #                      else
                    230: #                              kill $sig_stop `check_process $command`
                    231: #                      $sig_stop defaults to TERM.
                    232: #      reload          As stop, except use $sig_reload instead.
                    233: #                      $sig_reload defaults to HUP.
                    234: #      restart         Run `stop' then `start'.
                    235: #
                    236: run_rc_command()
                    237: {
                    238:        _arg=$1
                    239:        _ckvar=${rcvar:-$name}
                    240:        if [ -z "$_ckvar" ]; then
                    241:                err 3 'neither $rcvar or $name is set.'
                    242:        fi
                    243:
                    244:        case "$_arg" in
                    245:        fast*)
                    246:                _arg=${_arg#fast}
                    247:                _rc_fast_run=YES
                    248:                ;;
                    249:        force*)
                    250:                _arg=${_arg#force}
                    251:                eval ${_ckvar}=YES
                    252:                ;;
                    253:        esac
                    254:
1.16      lukem     255:        _keywords="start stop restart rcvar $extra_commands"
1.17      lukem     256:        _pid=
1.11      lukem     257:        _pidcmd=
                    258:        if [ -z "$_rc_fast_run" ]; then
                    259:                if [ -n "$pidfile" ]; then
                    260:                        _pidcmd='_pid=`check_pidfile '$pidfile' '$command'`'
                    261:                elif [ -n "$command" ]; then
                    262:                        _pidcmd='_pid=`check_process '$command'`'
                    263:                fi
                    264:                if [ -n "$_pidcmd" ]; then
                    265:                        _keywords="${_keywords} status"
                    266:                fi
                    267:        fi
                    268:
                    269:        if [ -z "$_arg" ]; then
                    270:                rc_usage "$_keywords"
                    271:        fi
                    272:
1.17      lukem     273:        if [ -n "$flags" ]; then        # allow override from environment
1.11      lukem     274:                _flags=$flags
                    275:        else
                    276:                eval _flags=\$${name}_flags
                    277:        fi
1.18      lukem     278:        eval _chdir=\$${name}_chdir
1.22      lukem     279:        eval _chroot=\$${name}_chroot
1.18      lukem     280:        eval _nice=\$${name}_nice
                    281:        eval _user=\$${name}_user
1.22      lukem     282:        eval _group=\$${name}_group
                    283:        eval _groups=\$${name}_groups
1.11      lukem     284:
                    285:        eval $_pidcmd
                    286:
                    287:        for _elem in $_keywords; do
                    288:                if [ "$_elem" != "$_arg" ]; then
                    289:                        continue
                    290:                fi
                    291:
                    292:                eval _cmd=\$${_arg}_cmd
                    293:                eval _precmd=\$${_arg}_precmd
                    294:                if [ -n "$_cmd" ]; then
                    295:                        eval $_precmd || return 1
                    296:                        eval $_cmd
                    297:                        return 0
                    298:                fi
                    299:
                    300:                case "$_arg" in
                    301:
                    302:                status)
                    303:                        if [ -n "$_pid" ]; then
                    304:                                echo "${name} is running as pid $_pid."
                    305:                        else
                    306:                                echo "${name} is not running."
                    307:                        fi
                    308:                        ;;
                    309:
                    310:                start)
                    311:                        if [ -n "$_pid" ]; then
                    312:                                echo "${name} already running? (pid=$_pid)."
                    313:                                exit 1
                    314:                        fi
                    315:
                    316:                        if ! checkyesno ${_ckvar} || [ ! -x $command ]; then
                    317:                                return 0
                    318:                        fi
                    319:
                    320:                        for _f in $required_vars; do
                    321:                                if ! checkyesno $_f; then
                    322:                                        warn \
                    323:                            "\$${_f} is not set; ${name} not started."
                    324:                                        return 1
                    325:                                fi
                    326:                        done
                    327:                        for _f in $required_dirs; do
                    328:                                if [ ! -d "${_f}/." ]; then
                    329:                                        warn \
                    330:                            "${_f} is not a directory; ${name} not started."
                    331:                                        return 1
                    332:                                fi
                    333:                        done
                    334:                        for _f in $required_files; do
                    335:                                if [ ! -r "${_f}" ]; then
                    336:                                        warn \
                    337:                        "${_f} is not readable; ${name} not started."
                    338:                                        return 1
                    339:                                fi
                    340:                        done
                    341:
                    342:                        eval $_precmd || return 1
                    343:                        echo "Starting ${name}."
1.22      lukem     344:                        if [ -n "$_chroot" ]; then
                    345:                                _doit="\
1.23    ! lukem     346: ${_nice:+nice -n $_nice }\
1.22      lukem     347: chroot ${_user:+-u $_user }${_group:+-g $_group }${_groups:+-G $_groups }\
                    348: $_chroot $command $_flags $command_args"
                    349:                        else
                    350:                                _doit="\
1.18      lukem     351: ${_user:+su -m $_user -c 'sh -c \"}\
                    352: ${_chdir:+cd $_chdir; }\
                    353: ${_nice:+nice -n $_nice }\
                    354: $command $_flags $command_args\
                    355: ${_user:+\"'}"
1.22      lukem     356:                        fi
1.18      lukem     357:                        eval $_doit
1.11      lukem     358:                        ;;
                    359:
                    360:                stop)
                    361:                        if [ -z "$_pid" ]; then
                    362:                                if checkyesno ${_ckvar}; then
                    363:                                        if [ -n "$pidfile" ]; then
                    364:                                                echo \
                    365:                                        "${name} not running? (check $pidfile)."
                    366:                                        else
                    367:                                                echo "${name} not running?"
                    368:                                        fi
                    369:                                        exit 1
                    370:                                fi
                    371:                                return 0
                    372:                        fi
                    373:
                    374:                        eval $_precmd || return 1
                    375:                        echo "Stopping ${name}."
1.18      lukem     376:                        _doit=\
                    377: "${_user:+su -m $_user -c '}kill -${sig_stop:-TERM} $_pid${_user:+'}"
                    378:                        eval $_doit
1.11      lukem     379:                        ;;
                    380:
                    381:                reload)
                    382:                        if [ -z "$_pid" ]; then
                    383:                                if checkyesno ${_ckvar}; then
                    384:                                        if [ -n "$pidfile" ]; then
                    385:                                                echo \
                    386:                                    "${name} not running? (check $pidfile)."
                    387:                                        else
                    388:                                                echo "${name} not running?"
                    389:                                        fi
                    390:                                        exit 1
                    391:                                fi
                    392:                                return 0
                    393:                        fi
                    394:                        echo "Reloading ${name} config files."
                    395:                        eval $_precmd || return 1
1.18      lukem     396:                        _doit=\
                    397: "${_user:+su -m $_user -c '}kill -${sig_reload:-HUP} $_pid${_user:+'}"
                    398:                        eval $_doit
1.11      lukem     399:                        ;;
                    400:
                    401:                restart)
                    402:                        if ! checkyesno ${_ckvar}; then
                    403:                                return 0
                    404:                        fi
                    405:                        eval $_precmd || return 1
                    406:                        ( $0 stop )
                    407:                        sleep 1
                    408:                        $0 start
                    409:
                    410:                        ;;
                    411:
                    412:                rcvar)
                    413:                        echo "# $name"
                    414:                        if checkyesno ${_ckvar}; then
                    415:                                echo "\$${_ckvar}=YES"
                    416:                        else
                    417:                                echo "\$${_ckvar}=NO"
                    418:                        fi
                    419:                        ;;
                    420:
                    421:                *)
                    422:                        rc_usage "$_keywords"
                    423:                        ;;
                    424:
                    425:                esac
                    426:                return 0
                    427:        done
                    428:
                    429:        echo 1>&2 "$0: unknown directive '$_arg'."
                    430:        rc_usage "$_keywords"
                    431:        exit 1
                    432: }
                    433:
                    434: #
                    435: # run_rc_script file arg
                    436: #      Start the script `file' with `arg', and correctly handle the
1.17      lukem     437: #      return value from the script.  If `file' ends with `.sh', it's
                    438: #      sourced into the current environment.  Otherwise it's run as
1.11      lukem     439: #      a child process.
1.17      lukem     440: #
1.11      lukem     441: #      Note: because `.sh' files are sourced into the current environment
                    442: #      run_rc_command shouldn't be used because its difficult to ensure
                    443: #      that the global variable state before and after the sourcing of
                    444: #      the .sh file won't adversely affect other scripts.
                    445: #
                    446: run_rc_script()
                    447: {
                    448:        _file=$1
                    449:        _arg=$2
                    450:        if [ -z "$_file" -o -z "$_arg" ]; then
                    451:                err 3 'USAGE: run_rc_script file arg'
                    452:        fi
                    453:
                    454:        case "$_file" in
1.17      lukem     455:        *.sh)                           # run in current shell
1.11      lukem     456:                set $_arg ; . $_file
                    457:                ;;
1.17      lukem     458:        *)                              # run in subshell
1.11      lukem     459:                ( set $_arg ; . $_file )
                    460:                ;;
                    461:        esac
                    462: }
1.19      lukem     463:
                    464: #
                    465: # load_rc_config
                    466: #      Source in the configuration file for a given command.
                    467: #
                    468: load_rc_config()
                    469: {
                    470:        _command=$1
                    471:        if [ -z "$_command" ]; then
                    472:                err 3 'USAGE: load_rc_config command'
                    473:        fi
                    474:
                    475:        . /etc/rc.conf
1.20      fvdl      476:        if [ -f /etc/rc.conf.d/"$_command" ]; then
                    477:                . /etc/rc.conf.d/"$_command"
                    478:        fi
1.19      lukem     479: }
                    480:
1.11      lukem     481:
                    482: #
                    483: # rc_usage commands
                    484: #      Print a usage string for $0, with `commands' being a list of
                    485: #      valid commands.
                    486: #
                    487: rc_usage()
                    488: {
                    489:        echo -n 1>&2 "Usage: $0 [fast|force]("
                    490:
                    491:        _sep=
                    492:        for _elem in $*; do
                    493:                echo -n 1>&2 "$_sep$_elem"
                    494:                _sep="|"
                    495:        done
                    496:        echo 1>&2 ")"
                    497:        exit 1
                    498: }
                    499:
                    500: #
                    501: # err exitval message
                    502: #      Display message to stderr and log to the syslog, and exit with exitval.
                    503: #
                    504: err()
                    505: {
                    506:        exitval=$1
                    507:        shift
                    508:
1.21      lukem     509:        logger "$0: ERROR: $*"
                    510:        echo 1>&2 "$0: ERROR: $*"
1.11      lukem     511:        exit $exitval
                    512: }
                    513:
                    514: #
                    515: # warn message
                    516: #      Display message to stderr and log to the syslog.
                    517: #
                    518: warn()
                    519: {
1.21      lukem     520:        logger "$0: WARNING: $*"
                    521:        echo 1>&2 "$0: WARNING: $*"
1.1       cjs       522: }

CVSweb <webmaster@jp.NetBSD.org>