/[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 846 - (show annotations) (download) (as text)
Thu Jan 13 20:28:50 2005 UTC (10 years ago) by uberlord
File MIME type: text/x-sh
File size: 11699 byte(s)
net dependancies corrected in runscript.sh - fixes #77839

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