/[vps]/baselayout-vserver/branches/baselayout-1_12/sbin/runscript.sh
Gentoo

Contents of /baselayout-vserver/branches/baselayout-1_12/sbin/runscript.sh

Parent Directory Parent Directory | Revision Log Revision Log


Revision 201 - (show annotations) (download) (as text)
Tue Jan 10 16:48:26 2006 UTC (8 years, 8 months ago) by phreak
File MIME type: text/x-sh
File size: 15192 byte(s)
Merging r1799
1 #!/bin/bash
2 # Copyright 1999-2006 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4
5 # Common functions
6 [[ ${RC_GOT_FUNCTIONS} != "yes" ]] && source /sbin/functions.sh
7 # Functions to handle dependencies and services
8 [[ ${RC_GOT_SERVICES} != "yes" ]] && source "${svclib}/sh/rc-services.sh"
9 # Functions to control daemons
10 [[ ${RC_GOT_DAEMON} != "yes" ]] && source "${svclib}/sh/rc-daemon.sh"
11
12 # User must be root to run most script stuff (except status)
13 if [[ ${EUID} != 0 ]] && ! [[ $2 == "status" && $# -eq 2 ]] ; then
14 eerror "$0: must be root to run init scripts"
15 exit 1
16 fi
17
18 # State variables
19 svcpause="no"
20 svcrestart="no"
21
22 myscript="$1"
23 if [[ -L $1 && ! -L /etc/init.d/${1##*/} ]] ; then
24 myservice="$(readlink $1)"
25 else
26 myservice="$1"
27 fi
28
29 myservice="${myservice##*/}"
30 export SVCNAME="${myservice}"
31 mylevel="$(<${svcdir}/softlevel)"
32
33 # Set $IFACE to the name of the network interface if it is a 'net.*' script
34 if [[ ${myservice%%.*} == "net" && ${myservice##*.} != "${myservice}" ]] ; then
35 IFACE="${myservice##*.}"
36 NETSERVICE="yes"
37 else
38 IFACE=
39 NETSERVICE=
40 fi
41
42 # Source configuration files.
43 # (1) Source /etc/conf.d/net if it is a net.* service
44 # (2) Source /etc/conf.d/${myservice} to get initscript-specific
45 # configuration (if it exists).
46 # (3) Source /etc/rc.conf to pick up potentially overriding
47 # configuration, if the system administrator chose to put it
48 # there (if it exists).
49 if [[ ${NETSERVICE} == "yes" ]]; then
50 conf="$(add_suffix /etc/conf.d/net)"
51 [[ -e ${conf} ]] && source "${conf}"
52 fi
53 conf="$(add_suffix /etc/conf.d/${myservice})"
54 [[ -e ${conf} ]] && source "${conf}"
55 conf="$(add_suffix /etc/rc.conf)"
56 [[ -e ${conf} ]] && source "${conf}"
57
58 usage() {
59 local IFS="|"
60 myline="Usage: ${myservice} { $* "
61 echo
62 eerror "${myline}}"
63 eerror " ${myservice} without arguments for full help"
64 }
65
66 stop() {
67 # Return success so the symlink gets removed
68 return 0
69 }
70
71 start() {
72 eerror "ERROR: \"${myservice}\" does not have a start function."
73 # Return failure so the symlink doesn't get created
74 return 1
75 }
76
77 restart() {
78 svc_restart || return $?
79 }
80
81 status() {
82 # Dummy function
83 return 0
84 }
85
86 svc_stop() {
87 local x= mydep= mydeps= retval=0 was_inactive=false
88 local -a servicelist=()
89
90 # Do not try to stop if it had already failed to do so on runlevel change
91 if is_runlevel_stop && service_failed "${myservice}" ; then
92 return 1
93 fi
94
95 if service_stopped "${myservice}" ; then
96 ewarn "WARNING: \"${myservice}\" has not yet been started."
97 return 0
98 fi
99
100 service_inactive "${myservice}" && was_inactive=true
101 if ! mark_service_stopping "${myservice}" ; then
102 ewarn "WARNING: \"${myservice}\" is already stopping."
103 return 0
104 fi
105 # Lock service starting too ...
106 mark_service_starting "${myservice}"
107 begin_service "${myservice}"
108 local begun=$?
109
110 service_message "Stopping service ${myservice}"
111
112 if in_runlevel "${myservice}" "${BOOTLEVEL}" && \
113 [[ ${SOFTLEVEL} != "reboot" && ${SOFTLEVEL} != "shutdown" ]] ; then
114 ewarn "WARNING: you are stopping a boot service."
115 fi
116
117 if [[ ${svcpause} != "yes" ]] ; then
118 if [[ ${NETSERVICE} == "yes" ]] ; then
119 # A net.* service
120 if in_runlevel "${myservice}" "${BOOTLEVEL}" || \
121 in_runlevel "${myservice}" "${mylevel}" ; then
122 # Only worry about net.* services if this is the last one running,
123 # or if RC_NET_STRICT_CHECKING is set ...
124 if ! is_net_up ; then
125 mydeps="net"
126 fi
127 fi
128
129 mydeps="${mydeps} ${myservice}"
130 else
131 mydeps="${myservice}"
132 fi
133 fi
134
135 # Save the IN_BACKGROUND var as we need to clear it for stopping depends
136 local ib_save="${IN_BACKGROUND}"
137 unset IN_BACKGROUND
138
139 for mydep in ${mydeps} ; do
140 for x in $(needsme "${mydep}") ; do
141 # Service not currently running, continue
142 if service_started "${x}" ; then
143 stop_service "${x}"
144 service_list=( "${service_list[@]}" "${x}" )
145 fi
146 done
147 done
148
149 for x in "${service_list[@]}" ; do
150 service_stopped "${x}" && continue
151 wait_service "${x}"
152 if ! service_stopped "${x}" ; then
153 retval=1
154 break
155 fi
156 done
157
158 IN_BACKGROUND="${ib_save}"
159
160 if [[ ${retval} != 0 ]] ; then
161 eerror "ERROR: problems stopping dependent services."
162 eerror " \"${myservice}\" is still up."
163 else
164 # Stop einfo/ebegin/eend from working as parallel messes us up
165 [[ ${RC_PARALLEL_STARTUP} == "yes" ]] && RC_QUIET_STDOUT="yes"
166
167 # Now that deps are stopped, stop our service
168 ( stop )
169 retval=$?
170
171 # If a service has been marked inactive, exit now as something
172 # may attempt to start it again later
173 if service_inactive "${myservice}" ; then
174 [[ ${begun} == 0 ]] && end_service "${myservice}" 0
175 return 0
176 fi
177 fi
178
179 if [[ ${retval} != 0 ]] ; then
180 # Did we fail to stop? create symlink to stop multible attempts at
181 # runlevel change. Note this is only used at runlevel change ...
182 is_runlevel_stop && mark_service_failed "${myservice}"
183
184 # If we are halting the system, do it as cleanly as possible
185 if [[ ${SOFTLEVEL} != "reboot" && ${SOFTLEVEL} != "shutdown" ]] ; then
186 if ${was_inactive} ; then
187 mark_service_inactive "${myservice}"
188 else
189 mark_service_started "${myservice}"
190 fi
191 fi
192
193 service_message "eerror" "FAILED to stop service ${myservice}!"
194 else
195 # If we're stopped from a daemon that sets ${IN_BACKGROUND} such as
196 # wpa_monitor when we mark as inactive instead of taking the down
197 if ${IN_BACKGROUND:-false} ; then
198 mark_service_inactive "${myservice}"
199 else
200 mark_service_stopped "${myservice}"
201 fi
202 service_message "Stopped service ${myservice}"
203 fi
204
205 [[ ${begun} == 0 ]] && end_service "${myservice}" "${retval}"
206 return "${retval}"
207 }
208
209 svc_start() {
210 local x= y= retval=0 was_inactive=false startfail="no"
211
212 # Do not try to start if i have done so already on runlevel change
213 if is_runlevel_start && service_failed "${myservice}" ; then
214 return 1
215 fi
216
217 if service_started "${myservice}" ; then
218 ewarn "WARNING: \"${myservice}\" has already been started."
219 return 0
220 elif service_stopping "${myservice}" ; then
221 eerror "ERROR: please wait for \"${myservice}\" to stop first."
222 return 1
223 elif service_inactive "${myservice}" ; then
224 if [[ ${IN_BACKGROUND} != "true" ]] ; then
225 ewarn "WARNING: \"${myservice}\" has already been started."
226 return 0
227 fi
228 fi
229
230 service_inactive "${myservice}" && was_inactive=true
231 if ! mark_service_starting "${myservice}" ; then
232 ewarn "WARNING: \"${myservice}\" is already starting."
233 return 0
234 fi
235 begin_service "${myservice}"
236 local begun=$?
237
238 service_message "Starting service ${myservice}"
239
240 local startupservices="$(trace_dependencies $(ineed "${myservice}") \
241 $(valid_iuse ${myservice}))"
242
243 # Start dependencies, if any
244 for x in ${startupservices} ; do
245 if [[ ${x} == "net" && ${NETSERVICE} != "yes" ]] && ! is_net_up ; then
246 local netservices="$(dolisting "/etc/runlevels/${BOOTLEVEL}/net.*") \
247 $(dolisting "/etc/runlevels/${mylevel}/net.*")"
248
249 for y in ${netservices} ; do
250 mynetservice="${y##*/}"
251 if service_stopped "${mynetservice}" ; then
252 start_service "${mynetservice}"
253 fi
254 done
255 elif [[ ${x} != "net" ]] ; then
256 if service_stopped "${x}" ; then
257 start_service "${x}"
258 fi
259 fi
260 done
261
262 # wait for dependencies to finish
263 for x in ${startupservices} ; do
264 if [ "${x}" = "net" -a "${NETSERVICE}" != "yes" ] ; then
265 for y in ${netservices} ; do
266 mynetservice="${y##*/}"
267
268 wait_service "${mynetservice}"
269
270 if ! service_started "${mynetservice}" ; then
271 # A 'need' dependency is critical for startup
272 if ineed -t "${myservice}" "${x}" >/dev/null ; then
273 # Only worry about a net.* service if we do not have one
274 # up and running already, or if RC_NET_STRICT_CHECKING
275 # is set ....
276 if ! is_net_up ; then
277 startfail="yes"
278 fi
279 fi
280 fi
281 done
282 elif [ "${x}" != "net" ] ; then
283 wait_service "${x}"
284 if ! service_started "${x}" ; then
285 # A 'need' dependacy is critical for startup
286 if ineed -t "${myservice}" "${x}" >/dev/null ; then
287 startfail="yes"
288 fi
289 fi
290 fi
291 done
292
293 if [[ ${startfail} == "yes" ]] ; then
294 eerror "ERROR: Problem starting needed services."
295 eerror " \"${myservice}\" was not started."
296 retval=1
297 elif broken "${myservice}" ; then
298 eerror "ERROR: Some services needed are missing. Run"
299 eerror " './${myservice} broken' for a list of those"
300 eerror " services. \"${myservice}\" was not started."
301 retval=1
302 else
303 (
304 exit() {
305 RC_QUIET_STDOUT="no"
306 eerror "DO NOT USE EXIT IN INIT.D SCRIPTS"
307 eerror "This IS a bug, please fix your broken init.d"
308 unset -f exit
309 exit $@
310 }
311 # Stop einfo/ebegin/eend from working as parallel messes us up
312 [[ ${RC_PARALLEL_STARTUP} == "yes" ]] && RC_QUIET_STDOUT="yes"
313 start
314 )
315 retval=$?
316
317 # If a service has been marked inactive, exit now as something
318 # may attempt to start it again later
319 if service_inactive "${myservice}" ; then
320 [[ ${begun} == 0 ]] && end_service "${myservice}" 1
321 return 1
322 fi
323 fi
324
325 if [[ ${retval} != 0 ]] ; then
326 is_runlevel_start && mark_service_failed "${myservice}"
327
328 # Remove link if service didn't start; but only if we're not booting
329 # If we're booting, we need to continue and do our best to get the
330 # system up.
331 if [[ ${SOFTLEVEL} != "${BOOTLEVEL}" ]]; then
332 if ${was_inactive} ; then
333 mark_service_inactive "${myservice}"
334 else
335 mark_service_stopped "${myservice}"
336 fi
337 fi
338
339 service_message "eerror" "FAILED to start service ${myservice}!"
340 else
341 mark_service_started "${myservice}"
342
343 service_message "Service ${myservice} started OK"
344 fi
345
346 [[ ${begun} == 0 ]] && end_service "${myservice}" "${retval}"
347 return "${retval}"
348 }
349
350 svc_restart() {
351 if ! service_stopped "${myservice}" ; then
352 svc_stop || return "$?"
353 fi
354 svc_start || return "$?"
355 }
356
357 svc_status() {
358 # The basic idea here is to have some sort of consistent
359 # output in the status() function which scripts can use
360 # as an generic means to detect status. Any other output
361 # should thus be formatted in the custom status() function
362 # to work with the printed " * status: foo".
363 local efunc="" state=""
364
365 # If we are effectively root, check to see if required daemons are running
366 # and update our status accordingly
367 [[ ${EUID} == 0 ]] && update_service_status "${myservice}"
368
369 if service_stopping "${myservice}" ; then
370 efunc="eerror"
371 state="stopping"
372 elif service_starting "${myservice}" ; then
373 efunc="einfo"
374 state="starting"
375 elif service_inactive "${myservice}" ; then
376 efunc="ewarn"
377 state="inactive"
378 elif service_started "${myservice}" ; then
379 efunc="einfo"
380 state="started"
381 else
382 efunc="eerror"
383 state="stopped"
384 fi
385 [[ ${RC_QUIET_STDOUT} != "yes" ]] \
386 && ${efunc} "status: ${state}"
387
388 status
389 [[ ${efunc} != "eerror" ]]
390 }
391
392 rcscript_errors=$(bash -n "${myscript}" 2>&1) || {
393 [[ -n ${rcscript_errors} ]] && echo "${rcscript_errors}" >&2
394 eerror "ERROR: \"${myscript}\" has syntax errors in it; aborting ..."
395 exit 1
396 }
397
398 # set *after* wrap_rcscript, else we get duplicates.
399 opts="start stop restart"
400
401 source "${myscript}"
402
403 # make sure whe have valid $opts
404 if [[ -z ${opts} ]] ; then
405 opts="start stop restart"
406 fi
407
408 svc_homegrown() {
409 local x arg=$1
410 shift
411
412 # Walk through the list of available options, looking for the
413 # requested one.
414 for x in ${opts} ; do
415 if [[ ${x} == "${arg}" ]] ; then
416 if typeset -F "${x}" &>/dev/null ; then
417 # Run the homegrown function
418 "${x}"
419
420 return $?
421 fi
422 fi
423 done
424 x=""
425
426 # If we're here, then the function wasn't in $opts.
427 [[ -n $* ]] && x="/ $* "
428 eerror "ERROR: wrong args ( "${arg}" ${x})"
429 # Do not quote this either ...
430 usage ${opts}
431 exit 1
432 }
433
434 shift
435 if [[ $# -lt 1 ]] ; then
436 eerror "ERROR: not enough args."
437 usage ${opts}
438 exit 1
439 fi
440 for arg in $* ; do
441 case "${arg}" in
442 --quiet)
443 RC_QUIET_STDOUT="yes"
444 ;;
445 # We check this in functions.sh ...
446 # --nocolor)
447 # RC_NOCOLOR="yes"
448 # ;;
449 --verbose)
450 RC_VERBOSE="yes"
451 ;;
452 esac
453 done
454 for arg in $* ; do
455 case "${arg}" in
456 stop)
457 if [[ -e "${svcdir}/restart/${myservice}" ]]; then
458 rm -f "${svcdir}/restart/${myservice}"
459 fi
460
461 # Stoped from the background - treat this as a restart so that
462 # stopped services come back up again when started.
463 if [[ ${IN_BACKGROUND} == "true" ]]; then
464 rm -rf "${svcdir}/snapshot/$$"
465 mkdir -p "${svcdir}/snapshot/$$"
466 cp -a "${svcdir}"/started/* "${svcdir}/snapshot/$$/"
467 fi
468
469 svc_stop
470
471 if [[ ${IN_BACKGROUND} == "true" ]]; then
472 res=
473 for x in $(dolisting "${svcdir}/snapshot/$$/") ; do
474 if service_stopped "${x##*/}" ; then
475 res="${res}${x##*/} "
476 fi
477 done
478 echo "${res}" > "${svcdir}/restart/${myservice}"
479 fi
480 ;;
481 start)
482 svc_start
483 retval=$?
484 if [[ -e "${svcdir}/restart/${myservice}" ]]; then
485 for x in $(trace_dependencies $(< "${svcdir}/restart/${myservice}")) ; do
486 service_stopped "${x}" && start_service "${x}"
487 done
488 rm -f "${svcdir}/restart/${myservice}"
489 fi
490 exit ${retval}
491 ;;
492 needsme|ineed|usesme|iuse|broken)
493 trace_dependencies "-${arg}"
494 ;;
495 status)
496 svc_status
497 ;;
498 zap)
499 if [[ -e "${svcdir}/restart/${myservice}" ]]; then
500 rm -f "${svcdir}/restart/${myservice}"
501 fi
502 if ! service_stopped "${myservice}" ; then
503 einfo "Manually resetting ${myservice} to stopped state."
504 mark_service_stopped "${myservice}"
505 end_service "${myservice}"
506 fi
507 ;;
508 restart)
509 svcrestart="yes"
510
511 # We don't kill child processes if we're restarting
512 # This is especically important for sshd ....
513 RC_KILL_CHILDREN="no"
514
515 # Create a snapshot of started services
516 rm -rf "${svcdir}/snapshot/$$"
517 mkdir -p "${svcdir}/snapshot/$$"
518 cp -a "${svcdir}"/started/* "${svcdir}/snapshot/$$/"
519
520 # Simple way to try and detect if the service use svc_{start,stop}
521 # to restart if it have a custom restart() funtion.
522 if [[ -n $(egrep '^[[:space:]]*restart[[:space:]]*()' "/etc/init.d/${myservice}") ]] ; then
523 if [[ -z $(egrep 'svc_stop' "/etc/init.d/${myservice}") || \
524 -z $(egrep 'svc_start' "/etc/init.d/${myservice}") ]] ; then
525 echo
526 ewarn "Please use 'svc_stop; svc_start' and not 'stop; start' to"
527 ewarn "restart the service in its custom 'restart()' function."
528 /var/lib/init.d/exclusive/net.lan ewarn "Run ${myservice} without arguments for more info."
529 echo
530 svc_restart
531 else
532 restart
533 fi
534 else
535 restart
536 fi
537
538 # Restart dependencies as well
539 if service_started "${myservice}" ; then
540 for x in $(trace_dependencies \
541 $(dolisting "${svcdir}/snapshot/$$/") ) ; do
542 if service_stopped "${x##*/}" ; then
543 start_service "${x##*/}"
544 fi
545 done
546 elif service_inactive "${myservice}" ; then
547 res=
548 for x in $(dolisting "${svcdir}/snapshot/$$/") ; do
549 if service_stopped "${x##*/}" ; then
550 res="${res}${x##*/} "
551 fi
552 done
553 echo "${res}" > "${svcdir}/restart/${myservice}"
554 fi
555
556 # Wait for any services that may still be running ...
557 [[ ${RC_PARALLEL_STARTUP} == "yes" ]] && wait
558
559 rm -rf "${svcdir}/snapshot/$$"
560 svcrestart="no"
561 ;;
562 pause)
563 svcpause="yes"
564 svc_stop
565 svcpause="no"
566 ;;
567 --quiet|--nocolor)
568 ;;
569 help)
570 exec "${svclib}"/sh/rc-help.sh "${myscript}" help
571 ;;
572 *)
573 # Allow for homegrown functions
574 svc_homegrown ${arg}
575 ;;
576 esac
577 done
578
579 # vim:ts=4

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.20