/[baselayout]/trunk/sbin/rc-services.sh
Gentoo

Contents of /trunk/sbin/rc-services.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, 8 months ago) by azarah
File MIME type: text/x-sh
File size: 12137 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 # Author: Martin Schlemmer <azarah@gentoo.org>
5 # $Header$
6
7 # RC Dependency and misc service functions
8
9
10 set -a
11
12 RC_GOT_SERVICES="yes"
13
14 [ "${RC_GOT_FUNCTIONS}" != "yes" ] && source /sbin/functions.sh
15 [ "${RC_GOT_DEPTREE_INFO}" != "yes" -a -f "${svcdir}/deptree" ] \
16 && source "${svcdir}/deptree"
17
18 if [ "${RC_GOT_DEPTREE_INFO}" != "yes" ]
19 then
20 eerror "Dependency info is missing! Please run"
21 echo
22 eerror " # /sbin/depscan.sh"
23 echo
24 eerror "to fix this."
25 fi
26
27
28 # bool get_dep_info(service)
29 #
30 # Set the Dependency variables to contain data for 'service'
31 #
32 get_dep_info() {
33 local myservice="$1"
34
35 # net.* services cause declare -x to bork
36 myservice="${myservice//\./DOT}"
37 # foo-bar services cause declare -x to bork
38 myservice="${myservice//-/DASH}"
39
40 [ -z "$1" ] && return 1
41
42 # We already have the right stuff ...
43 [ "${rc_name}" = "$1" ] && return 0
44
45 # If no 'depinfo_$1' function exist, then we have problems.
46 if [ -z "$(declare -F "depinfo_${myservice}")" ]
47 then
48 return 1
49 fi
50
51 "depinfo_${myservice}"
52
53 return 0
54 }
55
56 # string check_dependency(deptype, service1)
57 #
58 # List all the services that depend on 'service1' of dependency
59 # type 'deptype'
60 #
61 # bool check_dependency(deptype, -t, service1, service2)
62 #
63 # Returns true if 'service2' is a dependency of type 'deptype'
64 # of 'service1'
65 #
66 check_dependency() {
67 local x=
68
69 [ -z "$1" -o -z "$2" ] && return 1
70
71 # Set the dependency variables to relate to 'service1'
72 if [ "$2" = "-t" ]
73 then
74 [ -z "$3" -o -z "$4" ] && return 1
75
76 get_dep_info "$3" &>/dev/null || {
77 eerror "Could not get dependency info for \"$3\"!" > /dev/stderr
78 return 1
79 }
80 else
81 get_dep_info "$2" &>/dev/null || {
82 eerror "Could not get dependency info for \"$2\"!" > /dev/stderr
83 return 1
84 }
85 fi
86
87 # Do we have valid info for 'deptype' ?
88 [ -z "$(eval echo \${rc_$1})" ] && return 1
89
90 if [ "$2" = "-t" -a -n "$4" ]
91 then
92 # Check if 'service1' have 'deptype' dependency on 'service2'
93 for x in $(eval echo \${rc_$1})
94 do
95 [ "${x}" = "$4" ] && return 0
96 done
97 else
98 # Just list all services that 'service1' have 'deptype' dependency on.
99 eval echo "\${rc_$1}"
100
101 return 0
102 fi
103
104 return 1
105 }
106
107 # Same as for check_dependency, except 'deptype' is set to
108 # 'ineed'. It will return all the services 'service1' NEED's.
109 ineed() {
110 [ -z "$1" ] && return 1
111
112 check_dependency ineed $*
113
114 return $?
115 }
116
117 # Same as for check_dependency, except 'deptype' is set to
118 # 'needsme'. It will return all the services that NEED 'service1'.
119 needsme() {
120 [ -z "$1" ] && return 1
121
122 check_dependency needsme $*
123
124 return $?
125 }
126
127 # Same as for check_dependency, except 'deptype' is set to
128 # 'iuse'. It will return all the services 'service1' USE's.
129 iuse() {
130 [ -z "$1" ] && return 1
131
132 check_dependency iuse $*
133
134 return $?
135 }
136
137 # Same as for check_dependency, except 'deptype' is set to
138 # 'usesme'. It will return all the services that USE 'service1'.
139 usesme() {
140 [ -z "$1" ] && return 1
141
142 check_dependency usesme $*
143
144 return $?
145 }
146
147 # Same as for check_dependency, except 'deptype' is set to
148 # 'ibefore'. It will return all the services that are started
149 # *after* 'service1' (iow, it will start 'service1' before the
150 # list of services returned).
151 ibefore() {
152 [ -z "$1" ] && return 1
153
154 check_dependency ibefore $*
155
156 return $?
157 }
158
159 # Same as for check_dependency, except 'deptype' is set to
160 # 'iafter'. It will return all the services that are started
161 # *before* 'service1' (iow, it will start 'service1' after the
162 # list of services returned).
163 iafter() {
164 [ -z "$1" ] && return 1
165
166 check_dependency iafter $*
167
168 return $?
169 }
170
171 # Same as for check_dependency, except 'deptype' is set to
172 # 'broken'. It will return all the services that 'service1'
173 # NEED, but are not present.
174 broken() {
175 [ -z "$1" ] && return 1
176
177 check_dependency broken $*
178
179 return $?
180 }
181
182 # bool iparallel(service)
183 #
184 # Returns true if the service can be started in parallel.
185 #
186 iparallel() {
187 [ -z "$1" ] && return 1
188
189 if check_dependency parallel -t "$1" "no"
190 then
191 return 1
192 fi
193
194 return 0
195 }
196
197 # bool is_fake_service(service, runlevel)
198 #
199 # Returns ture if 'service' is a fake service in 'runlevel'.
200 #
201 is_fake_service() {
202 local x=
203 local fake_services=
204
205 [ -z "$1" -o -z "$2" ] && return 1
206
207 if [ "$2" != "${BOOTLEVEL}" -a \
208 -e "/etc/runlevels/${BOOTLEVEL}/.fake" ]
209 then
210 fake_services="$(< /etc/runlevels/${BOOTLEVEL}/.fake)"
211 fi
212
213 if [ -e "/etc/runlevels/$2/.fake" ]
214 then
215 fake_services="${fake_services} $(< /etc/runlevels/$2/.fake)"
216 fi
217
218 for x in ${fake_services}
219 do
220 if [ "$1" = "${x##*/}" ]
221 then
222 return 0
223 fi
224 done
225
226 return 1
227 }
228
229 # bool in_runlevel(service, runlevel)
230 #
231 # Returns true if 'service' is in runlevel 'runlevel'.
232 #
233 in_runlevel() {
234 [ -z "$1" -o -z "$2" ] && return 1
235
236 [ -L "/etc/runlevels/$2/$1" ] && return 0
237
238 return 1
239 }
240
241 # bool is_runlevel_start()
242 #
243 # Returns true if it is a runlevel change, and we are busy
244 # starting services.
245 #
246 is_runlevel_start() {
247 [ -d "${svcdir}/softscripts.old" ] && return 0
248
249 return 1
250 }
251
252 # bool is_runlevel_stop()
253 #
254 # Returns true if it is a runlevel change, and we are busy
255 # stopping services.
256 #
257 is_runlevel_stop() {
258 [ -d "${svcdir}/softscripts.new" ] && return 0
259
260 return 1
261 }
262
263 # void filter_environ()
264 #
265 # Tries to filter most of the dependency stuff from the environment
266 #
267 filter_environ() {
268 for x in $(declare -F)
269 do
270 if [ "${x/depinfo_}" != "${x}" ]
271 then
272 unset ${x/declare -f /}
273 fi
274 done
275
276 return 0
277 }
278
279 # int start_service(service)
280 #
281 # Start 'service' if it is not already running.
282 #
283 start_service() {
284 [ -z "$1" ] && return 1
285
286 if ! service_started "$1"
287 then
288 if is_fake_service "$1" "${SOFTLEVEL}"
289 then
290 mark_service_started "$1"
291 else
292 (. /sbin/runscript.sh "/etc/init.d/$1" start)
293
294 return $?
295 fi
296 fi
297
298 return 0
299 }
300
301 # int stop_service(service)
302 #
303 # Stop 'service' if it is not already running.
304 #
305 stop_service() {
306 [ -z "$1" ] && return 1
307
308 if service_started "$1"
309 then
310 if is_runlevel_stop
311 then
312 if is_fake_service "$1" "${OLDSOFTLEVEL}"
313 then
314 mark_service_stopped "$1"
315
316 return 0
317 fi
318 else
319 if is_fake_service "$1" "${SOFTLEVEL}"
320 then
321 mark_service_stopped "$1"
322
323 return 0
324 fi
325 fi
326
327 (. /sbin/runscript.sh "/etc/init.d/$1" stop)
328
329 return $?
330 fi
331
332 return 0
333 }
334
335 # bool mark_service_started(service)
336 #
337 # Mark 'service' as started.
338 #
339 mark_service_started() {
340 [ -z "$1" ] && return 1
341
342 ln -snf "/etc/init.d/$1" "${svcdir}/started/$1"
343
344 return $?
345 }
346
347 # bool mark_service_stopped(service)
348 #
349 # Mark 'service' as stopped.
350 #
351 mark_service_stopped() {
352 [ -z "$1" ] && return 1
353
354 rm -f "${svcdir}/started/$1"
355
356 return $?
357 }
358
359 # bool service_started(service)
360 #
361 # Returns true if 'service' is started
362 #
363 service_started() {
364 [ -z "$1" ] && return 1
365
366 if [ -L "${svcdir}/started/$1" ]
367 then
368 return 0
369 fi
370
371 return 1
372 }
373
374 # bool mark_service_failed(service)
375 #
376 # Mark service as failed for current runlevel. Note that
377 # this is only valid on runlevel change ...
378 #
379 mark_service_failed() {
380 [ -z "$1" ] && return 1
381
382 if [ -d "${svcdir}/failed" ]
383 then
384 ln -snf "/etc/init.d/$1" "${svcdir}/failed/$1"
385 return $?
386 fi
387
388 return 1
389 }
390
391 # bool service_failed(service)
392 #
393 # Return true if 'service' have failed during this runlevel.
394 #
395 service_failed() {
396 [ -z "$1" ] && return 1
397
398 if [ -L "${svcdir}/failed/$1" ]
399 then
400 return 0
401 fi
402
403 return 1
404 }
405
406 # bool net_service(service)
407 #
408 # Returns true if 'service' is a service controlling a network interface
409 #
410 net_service() {
411 [ -z "$1" ] && return 1
412
413 if [ "${1%%.*}" = "net" -a "${1##*.}" != "$1" ]
414 then
415 return 0
416 fi
417
418 return 0
419 }
420
421 # void schedule_service_startup(service)
422 #
423 # Schedule 'service' for startup, in parallel if possible.
424 #
425 schedule_service_startup() {
426 local count=0
427 local current_job=
428
429 if [ "${RC_PARALLEL_STARTUP}" = "yes" ]
430 then
431 set -m +b
432
433 if [ "$(jobs | grep -c "Running")" -gt 0 ]
434 then
435 if [ "$(jobs | grep -c "Running")" -eq 1 ]
436 then
437 if [ -n "$(jobs)" ]
438 then
439 current_job="$(jobs | awk '/Running/ { print $4}')"
440 fi
441
442 # Wait if we cannot start this service with the already running
443 # one (running one might start this one ...).
444 query_before "$1" "${current_job}" && wait
445
446 elif [ "$(jobs | grep -c "Running")" -ge 2 ]
447 then
448 count="$(jobs | grep -c "Running")"
449
450 # Wait until we have only one service running
451 while [ "${count}" -gt 1 ]
452 do
453 count="$(jobs | grep -c "Running")"
454 done
455
456 if [ -n "$(jobs)" ]
457 then
458 current_job="$(jobs | awk '/Running/ { print $4}')"
459 fi
460
461 # Wait if we cannot start this service with the already running
462 # one (running one might start this one ...).
463 query_before "$1" "${current_job}" && wait
464 fi
465 fi
466
467 if iparallel "$1"
468 then
469 eval start_service "$1" \&
470 else
471 # Do not start with any service running if we cannot start
472 # this service in parallel ...
473 # wait
474
475 start_service "$1"
476 fi
477 else
478 start_service "$1"
479 fi
480
481 # We do not need to check the return value here, as svc_{start,stop}() do
482 # their own error handling ...
483 return 0
484 }
485
486 # bool dependon(service1, service2)
487 #
488 # Does service1 depend (NEED or USE) on service2 ?
489 #
490 dependon() {
491 [ -z "$1" -o -z "$2" ] && return 1
492
493 if ineed -t "$1" "$2" || iuse -t "$1" "$2"
494 then
495 return 0
496 fi
497
498 return 1
499 }
500
501 # string valid_iuse(service)
502 #
503 # This will only give the valid use's for the service
504 # (they must be in the boot or current runlevel)
505 #
506 valid_iuse() {
507 local x=
508 local y=
509
510 for x in $(iuse "$1")
511 do
512 if [ -e "/etc/runlevels/boot/${x}" -o \
513 -e "/etc/runlevels/${mylevel}/${x}" ]
514 then
515 echo "${x}"
516 fi
517 done
518
519 return 0
520 }
521
522 # string valid_iafter(service)
523 #
524 # Valid services for current or boot rc level that should start
525 # before 'service'
526 #
527 valid_iafter() {
528 local x=
529
530 for x in $(iafter "$1")
531 do
532 if [ -e "/etc/runlevels/boot/${x}" -o \
533 -e "/etc/runlevels/${mylevel}/${x}" ]
534 then
535 echo "${x}"
536 fi
537 done
538
539 return 0
540 }
541
542 # void trace_depend(deptype, service, deplist)
543 #
544 # Trace the dependency tree of 'service' for type 'deptype', and
545 # modify 'deplist' with the info.
546 #
547 trace_depend() {
548 local x=
549 local y=
550 local add=
551
552 [ -z "$1" -o -z "$2" -o -z "$3" ] && return 1
553
554 # Build the list of services that 'deptype' on this one
555 for x in "$("$1" "$2")"
556 do
557 add="yes"
558
559 for y in $(eval echo "\${$3}")
560 do
561 [ "${x}" = "${y}" ] && add="no"
562 done
563
564 [ "${add}" = "yes" ] && eval $(echo "$3=\"\${$3} ${x}\"")
565
566 # Recurse to build a complete list ...
567 trace_depend "$1" "${x}" "$3"
568 done
569
570 return 0
571 }
572
573 # string list_depend_trace(deptype)
574 #
575 # Return resulting list of services for a trace of
576 # type 'deptype' for $myservice
577 #
578 list_depend_trace() {
579 local x=
580 local list=
581
582 [ -z "$1" ] && return 1
583
584 trace_depend "$1" "${myservice}" "list"
585
586 for x in ${list}
587 do
588 echo "${x}"
589 done
590
591 return 0
592 }
593
594 # bool query_before(service1, service2)
595 #
596 # Return true if 'service2' should be started *before*
597 # service1.
598 #
599 query_before() {
600 local x=
601 local list=
602 local netservice="no"
603
604 [ -z "$1" -o -z "$2" ] && return 1
605
606 trace_depend "ineed" "$1" "list"
607
608 for x in $1 ${list}
609 do
610 trace_depend "iuse" "${x}" "list"
611 done
612
613 for x in $1 ${list}
614 do
615 trace_depend "iafter" "${x}" "list"
616 done
617
618 net_service "$2" && netservice="yes"
619
620 for x in ${list}
621 do
622 [ "${x}" = "$2" ] && return 0
623
624 # Also match "net" if this is a network service ...
625 [ "${netservice}" = "yes" -a "${x}" = "net" ] && return 0
626 done
627
628 return 1
629 }
630
631 # bool query_after(service1, service2)
632 #
633 # Return true if 'service2' should be started *after*
634 # service1.
635 #
636 query_after() {
637 local x=
638 local list=
639 local netservice="no"
640
641 [ -z "$1" -o -z "$2" ] && return 1
642
643 trace_depend "needsme" "$1" "list"
644
645 for x in $1 ${list}
646 do
647 trace_depend "usesme" "${x}" "list"
648 done
649
650 for x in $1 ${list}
651 do
652 trace_depend "ibefore" "${x}" "list"
653 done
654
655 net_service "$2" && netservice="yes"
656
657 for x in ${list}
658 do
659 [ "${x}" = "$2" ] && return 0
660
661 # Also match "net" if this is a network service ...
662 [ "${netservice}" = "yes" -a "${x}" = "net" ] && return 0
663 done
664
665 return 1
666 }
667
668 set +a
669
670
671 # 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