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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.20