/[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 201 - (show annotations) (download) (as text)
Tue Jan 10 16:48:26 2006 UTC (8 years, 3 months ago) by phreak
File MIME type: text/x-sh
File size: 20231 byte(s)
Merging r1799
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" ]] && 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" ]] && 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 local tmp=$( < "${fifo}" &>/dev/null )
340 local exitstatus=$( < "${svcdir}/exitcodes/${service}" )
341
342 return "${exitstatus}"
343 }
344
345 # int start_service(service)
346 #
347 # Start 'service' if it is not already running.
348 #
349 start_service() {
350 local service="$1"
351 [[ -z ${service} ]] && return 1
352
353 if [[ ! -e "/etc/init.d/${service}" ]] ; then
354 mark_service_stopped "${service}"
355 return 1
356 fi
357
358 service_starting "${service}" && return 0
359 service_started "${service}" && return 0
360 service_inactive "${service}" && return 1
361
362 if is_fake_service "${service}" "${SOFTLEVEL}" ; then
363 mark_service_started "${service}"
364 return 0
365 fi
366
367 begin_service "${service}" || return 0
368 if [[ ${RC_PARALLEL_STARTUP} != "yes" || \
369 ${START_CRITICAL} == "yes" ]] ; then
370 # if we can not start the services in parallel
371 # then just start it and return the exit status
372 ( "/etc/init.d/${service}" start )
373 retval=$?
374 end_service "${service}" "${retval}"
375 return "${retval}"
376 else
377 # if parallel startup is allowed, start it in background
378 (
379 "/etc/init.d/${service}" start
380 retval=$?
381 end_service "${service}" "${retval}"
382 ) &
383 return 0
384 fi
385 }
386
387 # int stop_service(service)
388 #
389 # Stop 'service' if it is not already running.
390 #
391 stop_service() {
392 local service="$1"
393 [[ -z ${service} ]] && return 1
394
395 if [[ ! -e "/etc/init.d/${service}" ]] ; then
396 mark_service_stopped "${service}"
397 return 0
398 fi
399
400 service_stopping "${service}" && return 0
401 service_stopped "${service}" && return 0
402
403 local level="${SOFTLEVEL}"
404 is_runlevel_stop && level="${OLDSOFTLEVEL}"
405
406 if is_fake_service "${service}" "${level}" ; then
407 mark_service_stopped "${service}"
408 return 0
409 fi
410
411 begin_service "${service}" || return 0
412
413 if [[ ${RC_PARALLEL_STARTUP} != "yes" || \
414 ${STOP_CRITICAL} == "yes" ]] ; then
415 # if we can not start the services in parallel
416 # then just start it and return the exit status
417 ( "/etc/init.d/${service}" stop )
418 retval=$?
419 end_service "${service}" "${retval}"
420 return "${retval}"
421 else
422 # if parallel startup is allowed, start it in background
423 (
424 ( "/etc/init.d/${service}" stop )
425 retval=$?
426 end_service "${service}" "${retval}"
427 ) &
428 return 0
429 fi
430 }
431
432 # bool mark_service_starting(service)
433 #
434 # Mark 'service' as starting.
435 #
436 mark_service_starting() {
437 [[ -z $1 ]] && return 1
438
439 ln -sn "/etc/init.d/$1" "${svcdir}/starting/$1" 2>/dev/null || return 1
440
441 [[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1"
442 [[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1"
443 return 0
444 }
445
446 # bool mark_service_started(service)
447 #
448 # Mark 'service' as started.
449 #
450 mark_service_started() {
451 [[ -z $1 ]] && return 1
452
453 ln -snf "/etc/init.d/$1" "${svcdir}/started/$1"
454
455 [[ -f "${svcdir}/starting/$1" ]] && rm -f "${svcdir}/starting/$1"
456 [[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1"
457 [[ -f "${svcdir}/stopping/$1" ]] && rm -f "${svcdir}/stopping/$1"
458
459 return 0
460 }
461
462 # bool mark_service_inactive(service)
463 #
464 # Mark service as inactive
465 #
466 mark_service_inactive() {
467 [[ -z $1 ]] && return 1
468
469 ln -snf "/etc/init.d/$1" "${svcdir}/inactive/$1"
470
471 [[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1"
472 [[ -f "${svcdir}/starting/$1" ]] && rm -f "${svcdir}/starting/$1"
473 [[ -f "${svcdir}/stopping/$1" ]] && rm -f "${svcdir}/stopping/$1"
474
475 return 0
476 }
477
478 # bool mark_service_stopping(service)
479 #
480 # Mark 'service' as stopping.
481 #
482 mark_service_stopping() {
483 [[ -z $1 ]] && return 1
484
485 ln -sn "/etc/init.d/$1" "${svcdir}/stopping/$1" 2>/dev/null || return 1
486
487 [[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1"
488 [[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1"
489 return 0
490 }
491
492 # bool mark_service_stopped(service)
493 #
494 # Mark 'service' as stopped.
495 #
496 mark_service_stopped() {
497 [[ -z $1 ]] && return 1
498
499 [[ -f "${svcdir}/daemons/$1" ]] && rm -f "${svcdir}/daemons/$1"
500 [[ -f "${svcdir}/starting/$1" ]] && rm -f "${svcdir}/starting/$1"
501 [[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1"
502 [[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1"
503 [[ -f "${svcdir}/stopping/$1" ]] && rm -f "${svcdir}/stopping/$1"
504
505 return 0
506 }
507
508 # bool test_service_state(char *service, char *state)
509 #
510 # Returns 0 if the service link exists and points to a file, otherwise 1
511 # If 1 then the link is erased if it exists
512 test_service_state() {
513 [[ -z $1 || -z $2 ]] && return 1
514
515 local f="${svcdir}/$2/$1"
516
517 # Service is in the state requested
518 [[ -L ${f} ]] && return 0
519
520 [[ ! -e ${f} ]] && rm -f "${f}"
521 return 1
522 }
523
524 # bool service_starting(service)
525 #
526 # Returns true if 'service' is starting
527 #
528 service_starting() {
529 test_service_state "$1" "starting"
530 }
531
532 # bool service_started(service)
533 #
534 # Returns true if 'service' is started
535 #
536 service_started() {
537 test_service_state "$1" "started"
538 }
539
540 # bool service_inactive(service)
541 #
542 # Returns true if 'service' is inactive
543 #
544 service_inactive() {
545 test_service_state "$1" "inactive"
546 }
547
548 # bool service_stopping(service)
549 #
550 # Returns true if 'service' is stopping
551 #
552 service_stopping() {
553 test_service_state "$1" "stopping"
554 }
555
556 # bool service_stopped(service)
557 #
558 # Returns true if 'service' is stopped
559 #
560 service_stopped() {
561 [[ -z $1 ]] && return 1
562
563 service_starting "$1" && return 1
564 service_started "$1" && return 1
565 service_stopping "$1" && return 1
566 service_inactive "$1" && return 1
567
568 return 0
569 }
570
571 # bool mark_service_failed(service)
572 #
573 # Mark service as failed for current runlevel. Note that
574 # this is only valid on runlevel change ...
575 #
576 mark_service_failed() {
577 [[ -z $1 || ! -d "${svcdir}/failed" ]] && return 1
578
579 ln -snf "/etc/init.d/$1" "${svcdir}/failed/$1"
580 }
581
582 # bool service_failed(service)
583 #
584 # Return true if 'service' have failed during this runlevel.
585 #
586 service_failed() {
587 [[ -n $1 && -L "${svcdir}/failed/$1" ]]
588 }
589
590 # bool service_started_daemon(char *interface, char *daemon, int index)
591 # Returns 0 if the service started the given daemon
592 # via start-stop-daemon, otherwise 1.
593 # If index is emtpy, then we don't care what the first daemon launched
594 # was, otherwise the daemon must also be at that index
595 service_started_daemon() {
596 local service="$1" daemon="$2" index="${3:-[0-9]*}"
597 local daemonfile="${svcdir}/daemons/${service}"
598
599 [[ ! -e ${daemonfile} ]] && return 1
600 grep -q '^RC_DAEMONS\['"${index}"'\]="'${daemon}'"$' "${daemonfile}"
601 }
602
603 # bool net_service(service)
604 #
605 # Returns true if 'service' is a service controlling a network interface
606 #
607 net_service() {
608 [[ -n $1 && ${1%%.*} == "net" && ${1##*.} != "$1" ]]
609 }
610
611 # bool is_net_up()
612 #
613 # Return true if service 'net' is considered up, else false.
614 #
615 # Notes for RC_NET_STRICT_CHECKING values:
616 # none net is up without checking anything - usefull for vservers
617 # lo Interface 'lo' is counted and if only it is up, net is up.
618 # no Interface 'lo' is not counted, and net is down even with it up,
619 # so there have to be at least one other interface up.
620 # yes All interfaces must be up.
621 is_net_up() {
622 local netcount=0
623
624 case "${RC_NET_STRICT_CHECKING}" in
625 none)
626 return 0
627 ;;
628 lo)
629 netcount="$(ls -1 "${svcdir}"/started/net.* 2> /dev/null | \
630 egrep -c "\/net\..*$")"
631 ;;
632 *)
633 netcount="$(ls -1 "${svcdir}"/started/net.* 2> /dev/null | \
634 grep -v 'net\.lo' | egrep -c "\/net\..*$")"
635 ;;
636 esac
637
638 # Only worry about net.* services if this is the last one running,
639 # or if RC_NET_STRICT_CHECKING is set ...
640 if [[ "${netcount}" -lt 1 || ${RC_NET_STRICT_CHECKING} == "yes" ]] ; then
641 return 1
642 fi
643
644 return 0
645 }
646
647 # bool dependon(service1, service2)
648 #
649 # Does service1 depend (NEED or USE) on service2 ?
650 #
651 dependon() {
652 ineed -t "$1" "$2" || iuse -t "$1" "$2"
653 }
654
655 # string validi(use/after, service)
656 #
657 # This is the main code for valid_after and valid_iuse
658 # No point in writing it twice!
659 valid_i() {
660 local x
661 # Just set to dummy for now (don't know if $svcdir/softlevel exists yet).
662 local mylevel="${BOOTLEVEL}"
663
664 [[ $1 != "after" && $1 != "use" ]] && return 1
665
666 # Cannot be SOFTLEVEL, as we need to know current runlevel
667 [[ -f "${svcdir}/softlevel" ]] && mylevel=$( < "${svcdir}/softlevel" )
668
669 for x in $( i$1 "$2" ) ; do
670 [[ -e "/etc/runlevels/${BOOTLEVEL}/${x}" || \
671 -e "/etc/runlevels/${mylevel}/${x}" || \
672 ${x} == "net" ]] \
673 && echo "${x}"
674 done
675
676 return 0
677 }
678
679 # string valid_iuse(service)
680 #
681 # This will only give the valid use's for the service
682 # (they must be in the boot or current runlevel)
683 #
684 valid_iuse() {
685 valid_i "use" "$1"
686 }
687
688 #string valid_iafter(service)
689 #
690 # Valid services for current or boot rc level that should start
691 # before 'service'
692 #
693 valid_iafter() {
694 valid_i "after" "$1"
695 }
696
697 # string trace_dependencies(service[s])
698 #
699 # Get and sort the dependencies of given service[s].
700 #
701 trace_dependencies() {
702 local -a services=( "$@" ) net_deps
703 local i j net_services x
704
705 if [[ $1 == -* ]]; then
706 deptype="${1/-/}"
707 if net_service "${myservice}" ; then
708 services=( "net" "${myservice}" )
709 else
710 services=( "${myservice}" )
711 fi
712 fi
713
714 net_services=$( cd "${svcdir}"/started; ls net.* 2>/dev/null )
715 # If no net services are running or we only have net.lo up, then
716 # assume we are in boot runlevel or starting a new runlevel
717 if [[ -z ${net_services} || ${net_services} == "net.lo" ]]; then
718 get_net_services() {
719 local runlevel="$1"
720
721 if [[ -d "/etc/runlevels/${runlevel}" ]] ; then
722 cd "/etc/runlevels/${runlevel}"
723 ls net.* 2>/dev/null
724 fi
725 }
726
727 local mylevel="${BOOTLEVEL}"
728 local x=$( get_net_services "${mylevel}" )
729
730 [[ -f "${svcdir}/softlevel" ]] && mylevel=$( < "${svcdir}/softlevel" )
731 [[ ${BOOTLEVEL} != "${mylevel}" ]] && \
732 local x="${x} $( get_net_services "${mylevel}" )"
733 [[ -n ${x} ]] && net_services="${x}"
734 fi
735
736 # Cache the generic "net" depends
737 net_deps=( $( ineed net ) $( valid_iuse net ) )
738 if is_runlevel_start || is_runlevel_stop ; then
739 net_deps=( "${net_deps[@]}" $( valid_iafter net ) )
740 fi
741
742 # OK, this is a topological sort
743 # The bonus about doing it in bash is that we can calculate our sort
744 # order as we calculate our dependencies
745 local -a visited sorted
746 visit_service() {
747 local service="$1" dep x
748 local -a deps
749
750 [[ " ${visited[@]} " == *" ${service} "* ]] && return
751 visited=( "${visited[@]}" "${service}" )
752
753 if [[ -n ${deptype} ]] ; then
754 deps=( $( "${deptype}" "${service}" ) )
755 else
756 deps=( $( ineed "${service}" ) $( valid_iuse "${service}" ) )
757 if is_runlevel_start || is_runlevel_stop ; then
758 deps=( "${deps[@]}" $( valid_iafter "${service}" ) )
759 fi
760
761 # If we're a net service, we have to get deps for ourself
762 # and the net service as we're both
763 net_service "${service}" && deps=( "${deps[@]}" "${net_deps[@]}" )
764
765 x=" ${deps[@]} "
766 deps=( "${deps[@]}" ${x// net / ${net_services} } )
767 fi
768
769 services=( "${services[@]}" "${deps[@]}" )
770 for dep in ${deps[@]}; do
771 visit_service "${dep}"
772 done
773 sorted=( "${sorted[@]}" "${service}" )
774 }
775
776 for (( i=0; i<${#services[@]}; i++)); do
777 visit_service "${services[i]}"
778 done
779
780 services=( "${sorted[@]}" )
781
782 if [[ -n ${deptype} ]] ; then
783 # If deptype is set, we do not want the name of this service
784 x=" ${services[@]} "
785 services=( ${x// ${myservice} / } )
786
787 # If its a net service, do not include "net"
788 if net_service "${myservice}" ; then
789 x=" ${services[@]} "
790 sorted=( ${services// net / } )
791 fi
792 fi
793
794 echo "${services[@]}"
795 }
796
797 # bool query_before(service1, service2)
798 #
799 # Return true if 'service2' should be started *before*
800 # service1.
801 #
802 query_before() {
803 local x list
804 local netservice="no"
805
806 [[ -z $1 || -z $2 ]] && return 1
807
808 list=$( trace_dependencies "$1" )
809
810 net_service "$2" && netservice="yes"
811
812 for x in ${list} ; do
813 [[ ${x} == "$2" ]] && return 0
814
815 # Also match "net" if this is a network service ...
816 [[ ${netservice} == "yes" && ${x} == "net" ]] && return 0
817 done
818
819 return 1
820 }
821
822 # vim:ts=4

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.20