/[gentoo-alt]/trunk/baselayout-prefix/sbin/rc-services.sh
Gentoo

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.20