/[baselayout]/trunk/sbin/runscript.sh
Gentoo

Contents of /trunk/sbin/runscript.sh

Parent Directory Parent Directory | Revision Log Revision Log


Revision 389 - (show annotations) (download) (as text)
Mon Jul 28 01:23:46 2003 UTC (15 years, 9 months ago) by azarah
File MIME type: text/x-sh
File size: 12155 byte(s)
adelie fixes, add better logger support

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