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

Contents of /trunk/sbin/rc-services.sh

Parent Directory Parent Directory | Revision Log Revision Log


Revision 399 - (show annotations) (download) (as text)
Mon Aug 4 21:39:17 2003 UTC (15 years, 8 months ago) by azarah
File MIME type: text/x-sh
File size: 12594 byte(s)
Last minute fixes

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