/[vps]/baselayout-vserver/branches/baselayout-1_12/sbin/rc-services.sh
Gentoo

Contents of /baselayout-vserver/branches/baselayout-1_12/sbin/rc-services.sh

Parent Directory Parent Directory | Revision Log Revision Log


Revision 206 - (show annotations) (download) (as text)
Sun Jan 15 10:27:03 2006 UTC (9 years ago) by phreak
File MIME type: text/x-sh
File size: 20381 byte(s)
Merging r1822 for branches/baselayout-1_12
1 # Copyright 1999-2004 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3
4 # RC Dependency and misc service functions
5
6 RC_GOT_SERVICES="yes"
7
8 [[ ${RC_GOT_FUNCTIONS} != "yes" ]] && source /sbin/functions.sh
9
10 if [[ ${RC_GOT_DEPTREE_INFO} != "yes" ]] ; then
11 # Only try and update if we are root
12 if [[ ${EUID} == "0" ]] && ! /sbin/depscan.sh -u ; then
13 echo
14 eerror "Error running '/sbin/depscan.sh'!"
15 eerror "Please correct any problems above."
16 exit 1
17 fi
18
19 source "${svcdir}/deptree"
20 if [[ ${RC_GOT_DEPTREE_INFO} != "yes" ]] ; then
21 echo
22 eerror "Dependency info is missing! Please run"
23 eerror " # /sbin/depscan.sh"
24 eerror "to fix this."
25 exit 1
26 fi
27 fi
28
29 #####################
30 # Internal variables
31 #####################
32
33 # The name of the service whose dependency info we currently have
34 rc_name=
35 # The index of the service whose dependency info we currently have
36 rc_index=0
37 # Our dependency types ...
38 rc_ineed=
39 rc_needsme=
40 rc_iuse=
41 rc_usesme=
42 rc_ibefore=
43 rc_iafter=
44 rc_broken=
45 rc_mtime=
46
47 ############
48 # Functions
49 ############
50
51 # bool get_service_index(service, index)
52 #
53 # Print the index of 'service'. 'index' is the current index.
54 #
55 get_service_index() {
56 if [[ -z $1 || -z $2 ]] ; then
57 echo "0"
58 return 1
59 fi
60
61 local x myservice="$1" index="$2"
62
63 # Do we already have the index?
64 if [[ -n ${index} && ${index} -gt 0 \
65 && ${myservice} == "${RC_DEPEND_TREE[${index}]}" ]] ; then
66 echo "${index}"
67 return 0
68 fi
69
70 for (( x=1; x<=${RC_DEPEND_TREE[0]}; x++ )); do
71 index="$(( ${x} * ${rc_index_scale} ))"
72 if [[ ${myservice} == "${RC_DEPEND_TREE[${index}]}" ]] ; then
73 echo "${index}"
74 return 0
75 fi
76 done
77
78 echo "0"
79 return 1
80 }
81
82 # bool get_dep_info(service)
83 #
84 # Set the Dependency variables to contain data for 'service'
85 #
86 get_dep_info() {
87 [[ -z $1 ]] && return 1
88
89 local myservice="$1"
90
91 # We already have the right stuff ...
92 [[ ${myservice} == "${rc_name}" && -n ${rc_mtime} ]] && return 0
93
94 rc_index="$(get_service_index "${myservice}" "${rc_index}")"
95 rc_mtime="${RC_DEPEND_TREE[$((${rc_index} + ${rc_type_mtime}))]}"
96
97 # Verify that we have the correct index (rc_index) ...
98 # [[ ${rc_index} == "0" ]] && return 1
99
100 rc_name="${RC_DEPEND_TREE[${rc_index}]}"
101 rc_ineed="${RC_DEPEND_TREE[$((${rc_index} + ${rc_type_ineed}))]}"
102 rc_needsme="${RC_DEPEND_TREE[$((${rc_index} + ${rc_type_needsme}))]}"
103 rc_iuse="${RC_DEPEND_TREE[$((${rc_index} + ${rc_type_iuse}))]}"
104 rc_usesme="${RC_DEPEND_TREE[$((${rc_index} + ${rc_type_usesme}))]}"
105 rc_ibefore="${RC_DEPEND_TREE[$((${rc_index} + ${rc_type_ibefore}))]}"
106 rc_iafter="${RC_DEPEND_TREE[$((${rc_index} + ${rc_type_iafter}))]}"
107 rc_broken="${RC_DEPEND_TREE[$((${rc_index} + ${rc_type_broken}))]}"
108 rc_mtime="${RC_DEPEND_TREE[$((${rc_index} + ${rc_type_mtime}))]}"
109 return 0
110 }
111
112 # string check_dependency(deptype, service1)
113 #
114 # List all the services that depend on 'service1' of dependency
115 # type 'deptype'
116 #
117 # bool check_dependency(deptype, -t, service1, service2)
118 #
119 # Returns true if 'service2' is a dependency of type 'deptype'
120 # of 'service1'
121 #
122 check_dependency() {
123 [[ -z $1 || -z $2 ]] && return 1
124
125 local x myservice deps
126
127 # Set the dependency variables to relate to 'service1'
128 if [[ $2 == "-t" ]] ; then
129 [[ -z $3 || -z $4 ]] && return 1
130 myservice="$3"
131 else
132 myservice="$2"
133 fi
134
135 if ! get_dep_info "${myservice}" >/dev/null ; then
136 eerror "Could not get dependency info for ${myservice}!" > /dev/stderr
137 eerror "Please run:" > /dev/stderr
138 eerror " # /sbin/depscan.sh" > /dev/stderr
139 eerror "to try and fix this." > /dev/stderr
140 return 1
141 fi
142
143 # Do we have valid info for 'deptype' ?
144 eval deps=\"\$\{rc_$1\}\"
145 [[ -z ${deps} ]] && return 1
146
147 if [[ $2 == "-t" && -n $4 ]]; then
148 # Check if 'service1' have 'deptype' dependency on 'service2'
149 for x in ${deps} ; do
150 [[ ${x} == "$4" ]] && return 0
151 done
152 return 1
153 else
154 # Just list all services that 'service1' have 'deptype' dependency on.
155 echo "${deps}"
156 return 0
157 fi
158 }
159
160 # Same as for check_dependency, except 'deptype' is set to
161 # 'ineed'. It will return all the services 'service1' NEED's.
162 ineed() {
163 check_dependency ineed "$@"
164 }
165
166 # Same as for check_dependency, except 'deptype' is set to
167 # 'needsme'. It will return all the services that NEED 'service1'.
168 needsme() {
169 check_dependency needsme "$@"
170 }
171
172 # Same as for check_dependency, except 'deptype' is set to
173 # 'iuse'. It will return all the services 'service1' USE's.
174 iuse() {
175 check_dependency iuse "$@"
176 }
177
178 # Same as for check_dependency, except 'deptype' is set to
179 # 'usesme'. It will return all the services that USE 'service1'.
180 usesme() {
181 check_dependency usesme "$@"
182 }
183
184 # Same as for check_dependency, except 'deptype' is set to
185 # 'ibefore'. It will return all the services that are started
186 # *after* 'service1' (iow, it will start 'service1' before the
187 # list of services returned).
188 ibefore() {
189 check_dependency ibefore "$@"
190 }
191
192 # Same as for check_dependency, except 'deptype' is set to
193 # 'iafter'. It will return all the services that are started
194 # *before* 'service1' (iow, it will start 'service1' after the
195 # list of services returned).
196 iafter() {
197 check_dependency iafter "$@"
198 }
199
200 # Same as for check_dependency, except 'deptype' is set to
201 # 'broken'. It will return all the services that 'service1'
202 # NEED, but are not present.
203 broken() {
204 check_dependency broken "$@"
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 fake_services
213
214 [[ -z $1 || -z $2 ]] && return 1
215
216 [[ $2 != "${BOOTLEVEL}" && -e /etc/runlevels/"${BOOTLEVEL}"/.fake ]] && \
217 fake_services="$( < /etc/runlevels/"${BOOTLEVEL}"/.fake )"
218
219 [[ -e /etc/runlevels/"$2"/.fake ]] && \
220 fake_services="${fake_services} $( < /etc/runlevels/"$2"/.fake )"
221
222 for x in ${fake_services} ; do
223 [[ $1 == "${x##*/}" ]] && return 0
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 || -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" ]]
248 }
249
250 # bool is_runlevel_stop()
251 #
252 # Returns true if it is a runlevel change, and we are busy
253 # stopping services.
254 #
255 is_runlevel_stop() {
256 [[ -d "${svcdir}/softscripts.new" ]]
257 }
258
259 # void sevice_message([char *type] char *message)
260 #
261 # Print out a service message if we are on parallel
262 service_message() {
263 [[ ${RC_PARALLEL_STARTUP} != "yes" ]] && return
264
265 local cmd="einfo"
266 if [[ $1 == "1" || $1 == "error" || $1 == "eerror" ]] ; then
267 cmd="eerror"
268 shift
269 fi
270
271 local r="${RC_QUIET_STDOUT}"
272 RC_QUIET_STDOUT="no"
273 ${cmd} "$@"
274 RC_QUIET_STDOUT="${r}"
275 }
276
277 # bool begin_service( service )
278 #
279 # atomically marks the service as being executed
280 # use like this:
281 #
282 # if begin_service service ; then
283 # whatever is in here can only be executed by one process
284 # end_service service
285 # fi
286 begin_service() {
287 local service="$1"
288 [[ -z ${service} ]] && return 1
289
290 [[ ${START_CRITICAL} == "yes" || ${STOP_CRITICAL} == "yes" ]] && return 0
291
292 mkfifo "${svcdir}/exclusive/${service}" 2> /dev/null
293 }
294
295 # void end_service(service, exitcode)
296 #
297 # stops executing a exclusive region and
298 # wakes up anybody who is waiting for the exclusive region
299 #
300 end_service() {
301 local service="$1" exitstatus="$2"
302 [[ -z ${service} ]] && return
303
304 # if we are doing critical services, there is no fifo
305 [[ ${START_CRITICAL} == "yes" || ${STOP_CRITICAL} == "yes" ]] && return
306
307 if [[ -n ${exitstatus} ]] ; then
308 echo "${exitstatus}" > "${svcdir}/exitcodes/${service}"
309 fi
310
311 # move the fifo to a unique name so no-one is waiting for it
312 local fifo="${svcdir}/exclusive/${service}"
313 if [[ -e ${fifo} ]] ; then
314 local tempname="${fifo}.$$"
315 mv -f "${fifo}" "${tempname}"
316
317 # wake up anybody that was waiting for the fifo
318 touch "${tempname}"
319
320 # We dont need the fifo anymore
321 rm -f "${tempname}"
322 fi
323 }
324
325 # int wait_service(service)
326 #
327 # If a service has started, or a fifo does not exist return 0
328 # Otherwise, wait until we get an exit code via the fifo and return
329 # that instead.
330 wait_service() {
331 local service="$1"
332 local fifo="${svcdir}/exclusive/${service}"
333
334 [[ ${START_CRITICAL} == "yes" || ${STOP_CRITICAL} == "yes" ]] && return 0
335 [[ ! -e ${fifo} ]] && return 0
336
337 # This will block until the service fifo is touched
338 # Otheriwse we don't block
339 # We need to use cat instead of the bash inbuilt < so we don't see errors
340 local tmp="$( cat "${fifo}" 2>/dev/null )"
341 local exitstatus="$( < "${svcdir}/exitcodes/${service}" )"
342
343 return "${exitstatus}"
344 }
345
346 # int start_service(service)
347 #
348 # Start 'service' if it is not already running.
349 #
350 start_service() {
351 local service="$1"
352 [[ -z ${service} ]] && return 1
353
354 if [[ ! -e "/etc/init.d/${service}" ]] ; then
355 mark_service_stopped "${service}"
356 return 1
357 fi
358
359 service_starting "${service}" && return 0
360 service_started "${service}" && return 0
361 service_inactive "${service}" && return 1
362
363 if is_fake_service "${service}" "${SOFTLEVEL}" ; then
364 mark_service_started "${service}"
365 return 0
366 fi
367
368 begin_service "${service}" || return 0
369 if [[ ${RC_PARALLEL_STARTUP} != "yes" || \
370 ${START_CRITICAL} == "yes" ]] ; then
371 # if we can not start the services in parallel
372 # then just start it and return the exit status
373 ( "/etc/init.d/${service}" start )
374 retval=$?
375 end_service "${service}" "${retval}"
376 return "${retval}"
377 else
378 # if parallel startup is allowed, start it in background
379 (
380 "/etc/init.d/${service}" start
381 retval=$?
382 end_service "${service}" "${retval}"
383 ) &
384 return 0
385 fi
386 }
387
388 # int stop_service(service)
389 #
390 # Stop 'service' if it is not already running.
391 #
392 stop_service() {
393 local service="$1"
394 [[ -z ${service} ]] && return 1
395
396 if [[ ! -e "/etc/init.d/${service}" ]] ; then
397 mark_service_stopped "${service}"
398 return 0
399 fi
400
401 service_stopping "${service}" && return 0
402 service_stopped "${service}" && return 0
403
404 local level="${SOFTLEVEL}"
405 is_runlevel_stop && level="${OLDSOFTLEVEL}"
406
407 if is_fake_service "${service}" "${level}" ; then
408 mark_service_stopped "${service}"
409 return 0
410 fi
411
412 begin_service "${service}" || return 0
413
414 if [[ ${RC_PARALLEL_STARTUP} != "yes" || \
415 ${STOP_CRITICAL} == "yes" ]] ; then
416 # if we can not start the services in parallel
417 # then just start it and return the exit status
418 ( "/etc/init.d/${service}" stop )
419 retval=$?
420 end_service "${service}" "${retval}"
421 return "${retval}"
422 else
423 # if parallel startup is allowed, start it in background
424 (
425 ( "/etc/init.d/${service}" stop )
426 retval=$?
427 end_service "${service}" "${retval}"
428 ) &
429 return 0
430 fi
431 }
432
433 # bool mark_service_starting(service)
434 #
435 # Mark 'service' as starting.
436 #
437 mark_service_starting() {
438 [[ -z $1 ]] && return 1
439
440 ln -sn "/etc/init.d/$1" "${svcdir}/starting/$1" 2>/dev/null || return 1
441
442 [[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1"
443 [[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1"
444 return 0
445 }
446
447 # bool mark_service_started(service)
448 #
449 # Mark 'service' as started.
450 #
451 mark_service_started() {
452 [[ -z $1 ]] && return 1
453
454 ln -snf "/etc/init.d/$1" "${svcdir}/started/$1"
455
456 [[ -f "${svcdir}/starting/$1" ]] && rm -f "${svcdir}/starting/$1"
457 [[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1"
458 [[ -f "${svcdir}/stopping/$1" ]] && rm -f "${svcdir}/stopping/$1"
459
460 return 0
461 }
462
463 # bool mark_service_inactive(service)
464 #
465 # Mark service as inactive
466 #
467 mark_service_inactive() {
468 [[ -z $1 ]] && return 1
469
470 ln -snf "/etc/init.d/$1" "${svcdir}/inactive/$1"
471
472 [[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1"
473 [[ -f "${svcdir}/starting/$1" ]] && rm -f "${svcdir}/starting/$1"
474 [[ -f "${svcdir}/stopping/$1" ]] && rm -f "${svcdir}/stopping/$1"
475
476 return 0
477 }
478
479 # bool mark_service_stopping(service)
480 #
481 # Mark 'service' as stopping.
482 #
483 mark_service_stopping() {
484 [[ -z $1 ]] && return 1
485
486 ln -sn "/etc/init.d/$1" "${svcdir}/stopping/$1" 2>/dev/null || return 1
487
488 [[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1"
489 [[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1"
490 return 0
491 }
492
493 # bool mark_service_stopped(service)
494 #
495 # Mark 'service' as stopped.
496 #
497 mark_service_stopped() {
498 [[ -z $1 ]] && return 1
499
500 [[ -f "${svcdir}/daemons/$1" ]] && rm -f "${svcdir}/daemons/$1"
501 [[ -f "${svcdir}/starting/$1" ]] && rm -f "${svcdir}/starting/$1"
502 [[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1"
503 [[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1"
504 [[ -f "${svcdir}/stopping/$1" ]] && rm -f "${svcdir}/stopping/$1"
505
506 return 0
507 }
508
509 # bool test_service_state(char *service, char *state)
510 #
511 # Returns 0 if the service link exists and points to a file, otherwise 1
512 # If 1 then the link is erased if it exists
513 test_service_state() {
514 [[ -z $1 || -z $2 ]] && return 1
515
516 local f="${svcdir}/$2/$1"
517
518 # Service is in the state requested
519 [[ -L ${f} ]] && return 0
520
521 [[ ! -e ${f} ]] && rm -f "${f}"
522 return 1
523 }
524
525 # bool service_starting(service)
526 #
527 # Returns true if 'service' is starting
528 #
529 service_starting() {
530 test_service_state "$1" "starting"
531 }
532
533 # bool service_started(service)
534 #
535 # Returns true if 'service' is started
536 #
537 service_started() {
538 test_service_state "$1" "started"
539 }
540
541 # bool service_inactive(service)
542 #
543 # Returns true if 'service' is inactive
544 #
545 service_inactive() {
546 test_service_state "$1" "inactive"
547 }
548
549 # bool service_stopping(service)
550 #
551 # Returns true if 'service' is stopping
552 #
553 service_stopping() {
554 test_service_state "$1" "stopping"
555 }
556
557 # bool service_stopped(service)
558 #
559 # Returns true if 'service' is stopped
560 #
561 service_stopped() {
562 [[ -z $1 ]] && return 1
563
564 service_starting "$1" && return 1
565 service_started "$1" && return 1
566 service_stopping "$1" && return 1
567 service_inactive "$1" && return 1
568
569 return 0
570 }
571
572 # bool mark_service_failed(service)
573 #
574 # Mark service as failed for current runlevel. Note that
575 # this is only valid on runlevel change ...
576 #
577 mark_service_failed() {
578 [[ -z $1 || ! -d "${svcdir}/failed" ]] && return 1
579
580 ln -snf "/etc/init.d/$1" "${svcdir}/failed/$1"
581 }
582
583 # bool service_failed(service)
584 #
585 # Return true if 'service' have failed during this runlevel.
586 #
587 service_failed() {
588 [[ -n $1 && -L "${svcdir}/failed/$1" ]]
589 }
590
591 # bool service_started_daemon(char *interface, char *daemon, int index)
592 # Returns 0 if the service started the given daemon
593 # via start-stop-daemon, otherwise 1.
594 # If index is emtpy, then we don't care what the first daemon launched
595 # was, otherwise the daemon must also be at that index
596 service_started_daemon() {
597 local service="$1" daemon="$2" index="${3:-[0-9]*}"
598 local daemonfile="${svcdir}/daemons/${service}"
599
600 [[ ! -e ${daemonfile} ]] && return 1
601 grep -q '^RC_DAEMONS\['"${index}"'\]="'${daemon}'"$' "${daemonfile}"
602 }
603
604 # bool net_service(service)
605 #
606 # Returns true if 'service' is a service controlling a network interface
607 #
608 net_service() {
609 [[ -n $1 && ${1%%.*} == "net" && ${1##*.} != "$1" ]]
610 }
611
612 # bool is_net_up()
613 #
614 # Return true if service 'net' is considered up, else false.
615 #
616 # Notes for RC_NET_STRICT_CHECKING values:
617 # none net is up without checking anything - usefull for vservers
618 # lo Interface 'lo' is counted and if only it is up, net is up.
619 # no Interface 'lo' is not counted, and net is down even with it up,
620 # so there have to be at least one other interface up.
621 # yes All interfaces must be up.
622 is_net_up() {
623 local netcount=0
624
625 case "${RC_NET_STRICT_CHECKING}" in
626 none)
627 return 0
628 ;;
629 lo)
630 netcount="$(ls -1 "${svcdir}"/started/net.* 2> /dev/null | \
631 egrep -c "\/net\..*$")"
632 ;;
633 *)
634 netcount="$(ls -1 "${svcdir}"/started/net.* 2> /dev/null | \
635 grep -v 'net\.lo' | egrep -c "\/net\..*$")"
636 ;;
637 esac
638
639 # Only worry about net.* services if this is the last one running,
640 # or if RC_NET_STRICT_CHECKING is set ...
641 if [[ ${netcount} -lt 1 || ${RC_NET_STRICT_CHECKING} == "yes" ]] ; then
642 return 1
643 fi
644
645 return 0
646 }
647
648 # bool dependon(service1, service2)
649 #
650 # Does service1 depend (NEED or USE) on service2 ?
651 #
652 dependon() {
653 ineed -t "$1" "$2" || iuse -t "$1" "$2"
654 }
655
656 # string validi(use/after, service)
657 #
658 # This is the main code for valid_after and valid_iuse
659 # No point in writing it twice!
660 valid_i() {
661 local x
662 # Just set to dummy for now (don't know if $svcdir/softlevel exists yet).
663 local mylevel="${BOOTLEVEL}"
664
665 [[ $1 != "after" && $1 != "use" ]] && return 1
666
667 # Cannot be SOFTLEVEL, as we need to know current runlevel
668 [[ -f "${svcdir}/softlevel" ]] && mylevel=$( < "${svcdir}/softlevel" )
669
670 for x in $( i$1 "$2" ) ; do
671 [[ -e "/etc/runlevels/${BOOTLEVEL}/${x}" || \
672 -e "/etc/runlevels/${mylevel}/${x}" || \
673 ${x} == "net" ]] \
674 && echo "${x}"
675 done
676
677 return 0
678 }
679
680 # string valid_iuse(service)
681 #
682 # This will only give the valid use's for the service
683 # (they must be in the boot or current runlevel)
684 #
685 valid_iuse() {
686 valid_i "use" "$1"
687 }
688
689 #string valid_iafter(service)
690 #
691 # Valid services for current or boot rc level that should start
692 # before 'service'
693 #
694 valid_iafter() {
695 valid_i "after" "$1"
696 }
697
698 # string trace_dependencies(service[s])
699 #
700 # Get and sort the dependencies of given service[s].
701 #
702 trace_dependencies() {
703 local -a services=( "$@" ) net_deps
704 local i j net_services x
705
706 if [[ $1 == -* ]]; then
707 deptype="${1/-/}"
708 if net_service "${myservice}" ; then
709 services=( "net" "${myservice}" )
710 else
711 services=( "${myservice}" )
712 fi
713 fi
714
715 net_services="$( cd "${svcdir}"/started; ls net.* 2>/dev/null )"
716 # If no net services are running or we only have net.lo up, then
717 # assume we are in boot runlevel or starting a new runlevel
718 if [[ -z ${net_services} || ${net_services} == "net.lo" ]]; then
719 get_net_services() {
720 local runlevel="$1"
721
722 if [[ -d "/etc/runlevels/${runlevel}" ]] ; then
723 cd "/etc/runlevels/${runlevel}"
724 ls net.* 2>/dev/null
725 fi
726 }
727
728 local mylevel="${BOOTLEVEL}"
729 local x="$( get_net_services "${mylevel}" )"
730
731 [[ -f "${svcdir}/softlevel" ]] && mylevel="$( < "${svcdir}/softlevel" )"
732 [[ ${BOOTLEVEL} != "${mylevel}" ]] && \
733 local x="${x} $( get_net_services "${mylevel}" )"
734 [[ -n ${x} ]] && net_services="${x}"
735 fi
736
737 # Cache the generic "net" depends
738 net_deps=( $( ineed net ) $( valid_iuse net ) )
739 if is_runlevel_start || is_runlevel_stop ; then
740 net_deps=( "${net_deps[@]}" $( valid_iafter net ) )
741 fi
742
743 # OK, this is a topological sort
744 # The bonus about doing it in bash is that we can calculate our sort
745 # order as we calculate our dependencies
746 local -a visited sorted
747 visit_service() {
748 local service="$1" dep x
749 local -a deps
750
751 [[ " ${visited[@]} " == *" ${service} "* ]] && return
752 visited=( "${visited[@]}" "${service}" )
753
754 if [[ -n ${deptype} ]] ; then
755 deps=( $( "${deptype}" "${service}" ) )
756 else
757 deps=( $( ineed "${service}" ) $( valid_iuse "${service}" ) )
758 if is_runlevel_start || is_runlevel_stop ; then
759 deps=( "${deps[@]}" $( valid_iafter "${service}" ) )
760 fi
761
762 # If we're a net service, we have to get deps for ourself
763 # and the net service as we're both
764 net_service "${service}" && deps=( "${deps[@]}" "${net_deps[@]}" )
765
766 x=" ${deps[@]} "
767 deps=( "${deps[@]}" ${x// net / ${net_services} } )
768 fi
769
770 services=( "${services[@]}" "${deps[@]}" )
771 for dep in ${deps[@]}; do
772 visit_service "${dep}"
773 done
774 sorted=( "${sorted[@]}" "${service}" )
775 }
776
777 for (( i=0; i<${#services[@]}; i++)); do
778 visit_service "${services[i]}"
779 done
780
781 services=( "${sorted[@]}" )
782
783 if [[ -n ${deptype} ]] ; then
784 # If deptype is set, we do not want the name of this service
785 x=" ${services[@]} "
786 services=( ${x// ${myservice} / } )
787
788 # If its a net service, do not include "net"
789 if net_service "${myservice}" ; then
790 x=" ${services[@]} "
791 sorted=( ${services// net / } )
792 fi
793 fi
794
795 echo "${services[@]}"
796 }
797
798 # bool query_before(service1, service2)
799 #
800 # Return true if 'service2' should be started *before*
801 # service1.
802 #
803 query_before() {
804 local x list
805 local netservice="no"
806
807 [[ -z $1 || -z $2 ]] && return 1
808
809 list="$( trace_dependencies "$1" )"
810
811 net_service "$2" && netservice="yes"
812
813 for x in ${list} ; do
814 [[ ${x} == "$2" ]] && return 0
815
816 # Also match "net" if this is a network service ...
817 [[ ${netservice} == "yes" && ${x} == "net" ]] && return 0
818 done
819
820 return 1
821 }
822
823 # vim:ts=4

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.20