/[baselayout]/branches/rc-scripts-1_6/sbin/runscript.sh
Gentoo

Contents of /branches/rc-scripts-1_6/sbin/runscript.sh

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1081 - (show annotations) (download) (as text)
Sun Apr 10 01:15:49 2005 UTC (9 years, 3 months ago) by vapier
File MIME type: text/x-sh
File size: 12002 byte(s)
have the status function of init.d scripts affect the exit value #88319 by Josh Nichols

1 #!/bin/bash
2 # Copyright 1999-2005 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4 # $Header$
5
6 # Common functions
7 [[ ${RC_GOT_FUNCTIONS} != "yes" ]] && source /sbin/functions.sh
8 # Functions to handle dependencies and services
9 [[ ${RC_GOT_SERVICES} != "yes" ]] && source "${svclib}/sh/rc-services.sh"
10 # Functions to control daemons
11 [[ ${RC_GOT_DAEMON} != "yes" ]] && source "${svclib}/sh/rc-daemon.sh"
12
13 # Fix bug 48595
14 if [[ ${EUID} != 0 ]] ; then
15 eerror "$0: must be root to run init scripts"
16 exit 1
17 fi
18
19 # State variables
20 svcpause="no"
21 svcrestart="no"
22
23 myscript="$1"
24 if [[ -L $1 ]] && [[ ! -L /etc/init.d/${1##*/} ]] ; then
25 myservice=$(readlink "$1")
26 else
27 myservice=$1
28 fi
29
30 myservice=${myservice##*/}
31 mylevel=$(<"${svcdir}/softlevel")
32
33
34 # Set $IFACE to the name of the network interface if it is a 'net.*' script
35 if [[ ${myservice%%.*} == "net" ]] && [[ ${myservice##*.} != ${myservice} ]] ; then
36 IFACE=${myservice##*.}
37 NETSERVICE="yes"
38 else
39 IFACE=
40 NETSERVICE=
41 fi
42
43 # We need to stop hotplug from launching net scripts until the boot level
44 # has completed
45 if [[ ${NETSERVICE} == "yes" && ${IFACE} != "lo" ]] ; then
46 if [[ -z ${mylevel} || ${mylevel} == ${BOOTLEVEL} ]] ; then
47 eerror "$0: cannot start until the runlevel "${BOOTLEVEL}" has completed"
48 exit 1
49 fi
50 fi
51
52 # Source configuration files.
53 # (1) Source /etc/conf.d/${myservice} to get initscript-specific
54 # configuration (if it exists).
55 # (2) Source /etc/conf.d/net if it is a net.* service
56 # (3) Source /etc/rc.conf to pick up potentially overriding
57 # configuration, if the system administrator chose to put it
58 # there (if it exists).
59
60 [[ -e $(add_suffix /etc/conf.d/${myservice}) ]] && source "$(add_suffix /etc/conf.d/${myservice})"
61 [[ -e $(add_suffix /etc/conf.d/net) ]] && \
62 [[ ${NETSERVICE} == "yes" ]] && source "$(add_suffix /etc/conf.d/net)"
63 [[ -e $(add_suffix /etc/rc.conf) ]] && source "$(add_suffix /etc/rc.conf)"
64
65
66 usage() {
67 local IFS="|"
68 myline="Usage: ${myservice} { $* "
69 echo
70 eerror "${myline}}"
71 eerror " ${myservice} without arguments for full help"
72 }
73
74 stop() {
75 # Return success so the symlink gets removed
76 return 0
77 }
78
79 start() {
80 eerror "ERROR: \"${myservice}\" does not have a start function."
81 # Return failure so the symlink doesn't get created
82 return 1
83 }
84
85 restart() {
86 svc_restart || return $?
87 }
88
89 status() {
90 # Dummy function
91 return 0
92 }
93
94 svc_stop() {
95 local x=
96 local mydep=
97 local mydeps=
98 local retval=0
99 local ordservice=
100
101 if ! service_started "${myservice}" ; then
102 if [[ ${RC_QUIET_STDOUT} != "yes" ]] ; then
103 eerror "ERROR: \"${myservice}\" has not yet been started."
104 return 1
105 else
106 return 0
107 fi
108 fi
109
110 # Do not try to stop if it had already failed to do so on runlevel change
111 if is_runlevel_stop && service_failed "${myservice}" ; then
112 exit 1
113 fi
114
115 # Remove symlink to prevent recursion
116 mark_service_stopped "${myservice}"
117
118 if in_runlevel "${myservice}" "${BOOTLEVEL}" && \
119 [[ ${SOFTLEVEL} != "reboot" && ${SOFTLEVEL} != "shutdown" && ${SOFTLEVEL} != "single" ]]
120 then
121 ewarn "WARNING: you are stopping a boot service."
122 fi
123
124 if [[ ${svcpause} != "yes" ]] ; then
125 if [[ ${NETSERVICE} == "yes" ]] ; then
126 # A net.* service
127 if in_runlevel "${myservice}" "${BOOTLEVEL}" || \
128 in_runlevel "${myservice}" "${mylevel}"
129 then
130 # Only worry about net.* services if this is the last one running,
131 # or if RC_NET_STRICT_CHECKING is set ...
132 if ! is_net_up ; then
133 mydeps="net"
134 fi
135 fi
136
137 mydeps="${mydeps} ${myservice}"
138 else
139 mydeps="${myservice}"
140 fi
141 fi
142
143 for mydep in ${mydeps} ; do
144 # If some service 'need' $mydep, stop it first; or if it is a runlevel change,
145 # first stop all services that is started 'after' $mydep.
146 if needsme "${mydep}" >/dev/null || \
147 (is_runlevel_stop && ibefore "${mydep}" >/dev/null)
148 then
149 local servicelist="$(needsme "${mydep}")"
150
151 # On runlevel change, stop all services "after $mydep" first ...
152 is_runlevel_stop && servicelist="${servicelist} $(ibefore "${mydep}")"
153
154 for x in ${servicelist} ; do
155 # Make sure we have a relevant rc-script ...
156 if [[ ${x} != "net" && ! -f /etc/init.d/${x} ]] ; then
157 continue
158 fi
159
160 # Service not currently running, continue
161 service_started "${x}" || continue
162
163 if ibefore -t "${mydep}" "${x}" >/dev/null && \
164 [[ -L ${svcdir}/softscripts.new/${x} ]]
165 then
166 # Service do not 'need' $mydep, and is still present in
167 # new runlevel ...
168 continue
169 fi
170
171 stop_service "${x}"
172
173 if [[ $? -ne 0 ]] ; then
174 # If we are halting the system, try and get it down as
175 # clean as possible, else do not stop our service if
176 # a dependent service did not stop.
177 if needsme -t "${mydep}" "${x}" >/dev/null && \
178 [[ ${SOFTLEVEL} != "reboot" && ${SOFTLEVEL} != "shutdown" ]]
179 then
180 retval=1
181 fi
182
183 break
184 fi
185 done
186 fi
187 done
188
189 if [[ ${retval} -ne 0 ]] ; then
190 eerror "ERROR: problems stopping dependent services."
191 eerror " \"${myservice}\" is still up."
192 else
193 # Now that deps are stopped, stop our service
194 stop
195 retval="$?"
196 fi
197
198 if [[ ${retval} -ne 0 ]] ; then
199 # Did we fail to stop? create symlink to stop multible attempts at
200 # runlevel change. Note this is only used at runlevel change ...
201 if is_runlevel_stop ; then
202 mark_service_failed "${myservice}"
203 fi
204
205 # If we are halting the system, do it as cleanly as possible
206 if [[ ${SOFTLEVEL} != "reboot" && ${SOFTLEVEL} != "shutdown" ]] ; then
207 mark_service_started "${myservice}"
208 fi
209 fi
210
211 return "${retval}"
212 }
213
214 svc_start() {
215 local retval=0
216 local startfail="no"
217 local x=
218 local y=
219 local myserv=
220 local ordservice=
221
222 if ! service_started "${myservice}" ; then
223 # Do not try to start if i have done so already on runlevel change
224 if is_runlevel_start && service_failed "${myservice}" ; then
225 exit 1
226 fi
227
228 # Link first to prevent possible recursion
229 mark_service_started "${myservice}"
230
231 # On rc change, start all services "before $myservice" first
232 if is_runlevel_start ; then
233 startupservices="$(ineed "${myservice}") \
234 $(valid_iuse "${myservice}") \
235 $(valid_iafter "${myservice}")"
236 else
237 startupservices="$(ineed "${myservice}") \
238 $(valid_iuse "${myservice}")"
239 fi
240
241 # Start dependencies, if any
242 for x in ${startupservices} ; do
243 if [[ ${x} == "net" && ${NETSERVICE} != "yes" ]] && ! is_net_up ; then
244 local netservices="$(dolisting "/etc/runlevels/${BOOTLEVEL}/net.*") \
245 $(dolisting "/etc/runlevels/${mylevel}/net.*")"
246
247 for y in ${netservices} ; do
248 mynetservice="${y##*/}"
249
250 if ! service_started "${mynetservice}" ; then
251 start_service "${mynetservice}"
252
253 # A 'need' dependency is critical for startup
254 if [[ $? -ne 0 ]] && ineed -t "${myservice}" "${x}" >/dev/null ; then
255 # Only worry about a net.* service if we do not have one
256 # up and running already, or if RC_NET_STRICT_CHECKING
257 # is set ....
258 if ! is_net_up ; then
259 startfail="yes"
260 fi
261 fi
262 fi
263 done
264
265 elif [[ ${x} != "net" ]] ; then
266 if ! service_started "${x}" ; then
267 start_service "${x}"
268
269 # A 'need' dependacy is critical for startup
270 if [[ $? -ne 0 ]] && ineed -t "${myservice}" "${x}" >/dev/null ; then
271 startfail="yes"
272 fi
273 fi
274 fi
275 done
276
277 if [[ ${startfail} == "yes" ]] ; then
278 eerror "ERROR: Problem starting needed services."
279 eerror " \"${myservice}\" was not started."
280 retval=1
281 fi
282
283 # Start service
284 if [[ ${retval} -eq 0 ]] && broken "${myservice}" ; then
285 eerror "ERROR: Some services needed are missing. Run"
286 eerror " './${myservice} broken' for a list of those"
287 eerror " services. \"${myservice}\" was not started."
288 retval=1
289 elif [[ ${retval} -eq 0 ]] && ! broken "${myservice}" ; then
290 start
291 retval="$?"
292 fi
293
294 if [[ ${retval} -ne 0 ]] && is_runlevel_start ; then
295 mark_service_failed "${myservice}"
296 fi
297
298 # Remove link if service didn't start; but only if we're not booting
299 # if we're booting, we need to continue and do our best to get the
300 # system up.
301 if [[ ${retval} -ne 0 && ${SOFTLEVEL} != ${BOOTLEVEL} ]] ; then
302 mark_service_stopped "${myservice}"
303 fi
304
305 return "${retval}"
306 else
307 if [[ ${RC_QUIET_STDOUT} != "yes" ]] ; then
308 ewarn "WARNING: \"${myservice}\" has already been started."
309 fi
310
311 return 0
312 fi
313 }
314
315 svc_restart() {
316 if service_started "${myservice}" ; then
317 svc_stop || return "$?"
318 sleep 1
319 fi
320
321 svc_start || return "$?"
322 }
323
324 svc_status() {
325 # The basic idea here is to have some sort of consistent
326 # output in the status() function which scripts can use
327 # as an generic means to detect status. Any other output
328 # should thus be formatted in the custom status() function
329 # to work with the printed " * status: foo".
330 local efunc="" state=""
331
332 if service_started "${myservice}" ; then
333 efunc="einfo"
334 state="started"
335 else
336 efunc="eerror"
337 state="stopped"
338 fi
339 [[ ${RC_QUIET_STDOUT} != "yes" ]] \
340 && ${efunc} "status: ${state}"
341
342 status
343 [[ ${efunc} != "eerror" ]]
344 }
345
346 rcscript_errors=$(wrap_rcscript "${myscript}" 2>&1) || {
347 [[ -n ${rcscript_errors} ]] && echo "${rcscript_errors}" >&2
348 eerror "ERROR: \"${myscript}\" has syntax errors in it; not executing..."
349 exit 1
350 }
351
352 # set *after* wrap_rcscript, else we get duplicates.
353 opts=""
354
355 source "${myscript}"
356
357 # make sure whe have valid $opts
358 opts="start stop restart pause zap ${opts}"
359
360 svc_homegrown() {
361 local arg="$1"
362 local x=
363
364 # Walk through the list of available options, looking for the
365 # requested one.
366 for x in ${opts} ; do
367 if [[ ${x} == ${arg} ]] ; then
368 if typeset -F "${x}" &>/dev/null ; then
369 # Run the homegrown function
370 "${x}"
371
372 return $?
373 fi
374 fi
375 done
376
377 # If we're here, then the function wasn't in $opts.
378 eerror "ERROR: wrong args. ( "${arg}" / $* )"
379 # Do not quote this either ...
380 usage ${opts}
381 exit 1
382 }
383
384 shift
385 if [[ $# -lt 1 ]] ; then
386 eerror "ERROR: not enough args."
387 usage ${opts}
388 exit 1
389 fi
390 for arg in $* ; do
391 case "${arg}" in
392 --quiet)
393 RC_QUIET_STDOUT="yes"
394 ;;
395 # We check this in functions.sh ...
396 # --nocolor)
397 # RC_NOCOLOR="yes"
398 # ;;
399 --verbose)
400 RC_VERBOSE="yes"
401 ;;
402 esac
403 done
404 for arg in $* ; do
405 case "${arg}" in
406 stop)
407 svc_stop
408 ;;
409 start)
410 svc_start
411 ;;
412 needsme|ineed|usesme|iuse|broken)
413 list_depend_trace "${arg}"
414 ;;
415 status)
416 svc_status
417 ;;
418 zap)
419 if service_started "${myservice}" ; then
420 einfo "Manually resetting ${myservice} to stopped state."
421 mark_service_stopped "${myservice}"
422 fi
423 ;;
424 restart)
425 svcrestart="yes"
426
427 # Create a snapshot of started services
428 rm -rf "${svcdir}/snapshot/$$"
429 mkdir -p "${svcdir}/snapshot/$$"
430 cp -a "${svcdir}"/started/* "${svcdir}/snapshot/$$/"
431
432 # Simple way to try and detect if the service use svc_{start,stop}
433 # to restart if it have a custom restart() funtion.
434 if [[ -n $(egrep '^[[:space:]]*restart[[:space:]]*()' "/etc/init.d/${myservice}") ]] ; then
435 if [[ -z $(egrep 'svc_stop' "/etc/init.d/${myservice}") || \
436 -z $(egrep 'svc_start' "/etc/init.d/${myservice}") ]]
437 then
438 echo
439 ewarn "Please use 'svc_stop; svc_start' and not 'stop; start' to"
440 ewarn "restart the service in its custom 'restart()' function."
441 ewarn "Run ${myservice} without arguments for more info."
442 echo
443 svc_restart
444 else
445 restart
446 fi
447 else
448 restart
449 fi
450
451 # Restart dependencies as well
452 if service_started "${myservice}" ; then
453 for x in $(dolisting "${svcdir}/snapshot/$$/") ; do
454 if ! service_started "${x##*/}" ; then
455 # schedule_service_startup "${x##*/}"
456 start_service "${x##*/}"
457 fi
458 done
459 fi
460
461 # Wait for any services that may still be running ...
462 # [[ ${RC_PARALLEL_STARTUP} == "yes" ]] && wait
463
464 rm -rf "${svcdir}/snapshot/$$"
465 svcrestart="no"
466 ;;
467 pause)
468 svcpause="yes"
469 svc_stop
470 svcpause="no"
471 ;;
472 --quiet|--nocolor)
473 ;;
474 *)
475 # Allow for homegrown functions
476 svc_homegrown ${arg}
477 ;;
478 esac
479 done
480
481
482 # vim:ts=4

Properties

Name Value
svn:eol-style native
svn:executable *
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.20