/[baselayout]/branches/bsd-porting-2/sbin/rc-services.sh
Gentoo

Contents of /branches/bsd-porting-2/sbin/rc-services.sh

Parent Directory Parent Directory | Revision Log Revision Log


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