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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.20