/[baselayout]/branches/rc-scripts-1_6/net-scripts/init.d/net.lo
Gentoo

Contents of /branches/rc-scripts-1_6/net-scripts/init.d/net.lo

Parent Directory Parent Directory | Revision Log Revision Log


Revision 777 - (show annotations) (download)
Sun Dec 12 10:47:05 2004 UTC (9 years, 7 months ago) by uberlord
File size: 23181 byte(s)
fixed installed typo in net.lo - fixes #74152. Thanks to Federico Galassi

1 #!/sbin/runscript
2 # net-scripts main code
3 # Version 1.0.5
4 # Copyright (c) 2004 Gentoo Foundation
5 # Distributed under the terms of the GNU General Public License V2
6 # Contributed by Roy Marples (uberlord@gentoo.org)
7 # Many thanks to Aron Griffis (agriffis@gentoo.org)
8 # for help, ideas and patches
9
10 #NB: Config is in /etc/conf.d/net
11
12 if [[ -n ${NET_DEBUG} ]]; then
13 set -x
14 devnull=/dev/stderr
15 else
16 devnull=/dev/null
17 fi
18
19 # For pcmcia users. note that pcmcia must be added to the same
20 # runlevel as the net.* script that needs it.
21 depend() {
22 use coldplug hotplug pcmcia usb isdn4linux wlan
23 }
24
25 # Define where our modules are
26 MODULES_DIR=/lib/rcscripts/net.modules.d
27
28 # Load some functions shared between ourselves and our dhcp helpers
29 source ${MODULES_DIR}/helpers.d/functions
30
31 # Make some wrappers to fudge after/before/need/use depend flags.
32 # These are callbacks so mods[i] will be set.
33 after() {
34 local x="$*"
35 [[ $# -gt 1 ]] && x=$( echo -e "${x// /\n}" | sort | xargs )
36 eval "${MODULE}_after() { echo \"$x\"; }"
37 }
38 before() {
39 local x="$*"
40 [[ $# -gt 1 ]] && x=$( echo -e "${x// /\n}" | sort | xargs )
41 eval "${MODULE}_before() { echo \"$x\"; }"
42 }
43 need() {
44 local x="$*"
45 [[ $# -gt 1 ]] && x=$( echo -e "${x// /\n}" | sort | xargs )
46 eval "${MODULE}_need() { echo \"$x\"; }"
47 }
48 installed() {
49 local x="$*"
50 [[ $# -gt 1 ]] && x=$( echo -e "${x// /\n}" | sort | xargs )
51 # We deliberately misspell this as _installed will probably be used
52 # at some point
53 eval "${MODULE}_instlled() { echo \"$x\"; }"
54 }
55
56 sort() {
57 LC_ALL=C /bin/sort "$@"
58 }
59
60 # bool net_start(char *iface)
61 #
62 # Starts a net.${iface} if required
63 # This is used by bridge and bond modules as the interfaces
64 # they need may have to be created
65 net_start() {
66 local iface=${1}
67
68 interface_exists ${iface} && return 0
69 [[ -f ${svcdir}/started/net.${iface} ]] && return 0
70 if [[ ! -x /etc/init.d/net.${iface} ]]; then
71 eerror "/etc/init.d/net.${iface} does not exist"
72 eerror "Cannot start ${iface}"
73 return 1
74 fi
75 /etc/init.d/net.${iface} start
76 return $?
77 }
78
79 # void module_class_wrap(char *module, char *provides)
80 # Setup class wrappers: interface_up -> iproute2_up, for example
81 module_class_wrap() {
82 local module=${1} provides=${2} x
83
84 # Don't wrap functions if another module already has
85 [[ $( type -t ${provides}_provides ) == function ]] && return
86
87 for x in $( typeset -f | grep -o ^${module}_'[^ ]*' ); do
88 eval "${provides}${x#${module}}() { ${x} \"\$@\"; }"
89 done
90 }
91
92 # bool module_load_minimum(char *module)
93 #
94 # Does the minimum checking on a module - even when forcing
95 module_load_minimum() {
96 local f=${1} MODULE=${1##*/}
97
98 if [[ ! -f ${f} ]]; then
99 eerror "${f} does not exist"
100 return 1
101 fi
102
103 if ! source ${f} ; then
104 eerror "${MODULE} failed a sanity check"
105 return 1
106 fi
107
108 for f in check_installed provides check_depends depend; do
109 [[ $( type -t ${MODULE}_${f} ) == function ]] && continue
110 eerror "${MODULE} does not support the required function ${f}"
111 return 1
112 done
113
114 # Wrap our before/after/need/use functions
115 ${MODULE}_depend
116
117 return 0
118 }
119
120 # bool modules_load_auto()
121 #
122 # Load and check each module for sanity
123 # If the module is not installed, the functions are to be removed
124 modules_load_auto() {
125 local e f i j beforefuncs afterfuncs diffs unload
126
127 # Populate the MODULES array
128 MODULES=( $( find ${MODULES_DIR}/ -maxdepth 1 -type f | sort ) )
129
130 # Each of these sources into the global namespace, so it's
131 # important that module functions and variables are prefixed with
132 # the module name, for example iproute2_
133
134 beforefuncs="$( typeset -F )"
135 j=${#MODULES[@]}
136 loaded_interface=false
137 for (( i=0; i<j; i++ )); do
138
139 unload=false
140 module_load_minimum ${MODULES[i]} || unload=true
141 MODULES[i]=${MODULES[i]##*/}
142
143 ! ${unload} && ${MODULES[i]}_check_installed false || unload=true
144
145 if [[ ${MODULES[i]} == interface ]]; then
146 eerror "interface is a reserved name - cannot load a module called interface"
147 return 1
148 fi
149
150 afterfuncs="$( typeset -F )"
151 if ${unload} ; then
152 unset MODULES[i]
153 unsetfuncs="${unsetfuncs} $( diff -U0 <( echo "${beforefuncs}" ) <( echo "${afterfuncs}" ) 2>/dev/null \
154 | awk 'BEGIN { ORS = " "; } /+declare -f/ { print $3; }' )"
155 fi
156 beforefuncs="${afterfuncs}"
157
158 done
159 MODULES=( "${MODULES[@]}" )
160
161 return 0
162 }
163
164
165 # bool modules_check_installed(void)
166 #
167 # Ensure that all modules have the required modules loaded
168 # This enables us to remove modules from the MODULES array
169 # Whilst other modules can still explicitly call them
170 # One example of this is essidnet which configures network
171 # settings for the specific ESSID connected to as the user
172 # may be using a daemon to configure wireless instead of our
173 # iwconfig module
174 modules_check_installed() {
175 local i j missingdeps nmods=${#MODULES[@]}
176
177 for (( i=0; i<nmods; i++ )); do
178 [[ $( type -t ${MODULES[i]}_instlled ) != function ]] && continue
179 for j in $( ${MODULES[i]}_instlled ); do
180 missingdeps=true
181 if [[ $( type -t ${j}_check_installed ) == function ]]; then
182 ${j}_check_installed && missingdeps=false
183 fi
184 ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break
185 done
186 done
187
188 MODULES=( "${MODULES[@]}" )
189 PROVIDES=( "${PROVIDES[@]}" )
190 }
191
192 # bool modules_check_user(void)
193 modules_check_user() {
194 local -a umods
195 local i j k l npref nmods=${#MODULES[@]}
196
197 # Has the interface got any specific modules?
198 eval umods=( \"\$\{modules_${iface}\[@\]\}\" )
199
200 # Global setting follows interface-specific setting
201 umods=( "${umods[@]}" "${modules[@]}" )
202
203 # Add our preferred modules
204 npref=3
205 umods=( "${umods[@]}" "ifconfig" "dhcpcd" "iwconfig" )
206
207 # First we strip any modules that conflict from user settings
208 # So if the user specifies pump then we don't use dhcpcd
209 for (( i=0; i<${#umods[@]}; i++ )); do
210 # Some users will inevitably put "dhcp" in their modules
211 # list. To keep users from screwing up their system this
212 # way, ignore this setting so that the default dhcp
213 # module will be used.
214 [[ ${umods[i]} == dhcp ]] && continue
215
216 # We remove any modules we explicitly don't want
217 if [[ ${umods[i]} == !* ]]; then
218 for (( j=0; j<nmods; j++ )); do
219 [[ -z ${MODULES[j]} ]] && continue
220 if [[ ${umods[i]:1} == ${MODULES[j]} || ${umods[i]:1} == ${PROVIDES[j]} ]]; then
221 # We may need to setup a class wrapper for it even though
222 # we don't use it directly
223 ${MODULES[j]}_check_installed && module_class_wrap ${MODULES[j]}
224 unset MODULES[j]
225 unset PROVIDES[j]
226 break
227 fi
228 done
229 continue
230 fi
231
232 if [[ $( type -t ${umods[i]}_provides ) != function ]]; then
233 # If the module is one of our preferred modules, then
234 # ignore this error; whatever is available will be
235 # used instead.
236 (( i < ${#umods[@]} - npref )) || continue
237 eerror "${umods[i]} is not a valid module (missing provides)"
238 return 1
239 fi
240
241 # Ensure that the user specified module has its package installed
242 if (( i < ${#umods[@]} - npref )); then
243 # $1==true causes check_installed to report its own errors
244 ${umods[i]}_check_installed true || return 1
245 else
246 # If this happens on a preferred modules, ignore it;
247 # whatever is available will be used instead.
248 ${umods[i]}_check_installed false || continue
249 fi
250
251 mod=$( ${umods[i]}_provides )
252 for (( j=0; j<nmods; j++ )); do
253 [[ -z ${MODULES[j]} ]] && continue
254 if [[ ${PROVIDES[j]} == ${mod} && ${umods[i]} != ${MODULES[j]} ]]; then
255 # We don't have a match - now ensure that we still provide an alternative.
256 # This is to handle our preferred modules.
257 for (( l=0; l<nmods; l++ )); do
258 [[ ${l} -eq ${j} || -z ${MODULES[l]} ]] && continue
259 if [[ ${PROVIDES[l]} == ${mod} ]]; then
260 unset MODULES[j]
261 unset PROVIDES[j]
262 break
263 fi
264 done
265 fi
266 done
267 done
268
269 # Then we strip conflicting modules.
270 # We only need to do this for 3rd party modules that conflict with
271 # our own modules and the preferred list AND the user modules
272 # list doesn't specify a preference.
273 for (( i=0; i<nmods-1; i++ )); do
274 [[ -z ${MODULES[i]} ]] && continue
275 for (( j=i+1; j<nmods; j++)); do
276 [[ -z ${MODULES[j]} ]] && continue
277 [[ ${PROVIDES[i]} == ${PROVIDES[j]} ]] && unset MODULES[j] && unset PROVIDES[j]
278 done
279 done
280
281 MODULES=( "${MODULES[@]}" )
282 PROVIDES=( "${PROVIDES[@]}" )
283 return 0
284 }
285
286 # void modules_sort(void)
287
288 modules_sort() {
289 local -a modnums sort_history modafter modbefore
290 local i j k p changed_something nmods=${#MODULES[@]}
291
292 # Sort our modules
293 # We do this by assigning numbers to each module
294 # We also assign modbefore and modafter so we don't
295 # shell out as much because it's expensive on CPU.
296 modnums=()
297 for (( i=0; i<nmods; i++ )); do
298 modnums[i]=${i}
299 [[ $( type -t ${MODULES[i]}_after ) == function ]] && modafter[i]=$( ${MODULES[i]}_after )
300 [[ $( type -t ${MODULES[i]}_before ) == function ]] && modbefore[i]=$( ${MODULES[i]}_before )
301 done
302
303 # Then we swap numbers based on and after/before flags
304 # until we don't swap anymore. The sort_history array prevents
305 # the possibility of an infinite loop
306 sort_history[0]="${modnums[*]}"
307 for (( k=1; 1; k++ )); do
308 changed_something=false
309 for (( i=0; i<nmods; i++ )); do
310 for p in ${modafter[i]}; do
311 for (( j=0; j<nmods; j++ )); do
312 [[ ${p} != ${MODULES[j]} && ${p} != ${PROVIDES[j]} ]] && continue
313 if [[ ${modnums[i]} -lt ${modnums[j]} ]]; then
314 tmp=${modnums[i]}
315 modnums[i]=${modnums[j]}
316 modnums[j]=${tmp}
317 changed_something=true
318 fi
319 done
320 done
321 for p in ${modbefore[i]}; do
322 for (( j=0; j<nmods; j++ )); do
323 [[ ${p} != ${MODULES[j]} && ${p} != ${PROVIDES[j]} ]] && continue
324 if [[ ${modnums[i]} -gt ${modnums[j]} ]]; then
325 tmp=${modnums[i]}
326 modnums[i]=${modnums[j]}
327 modnums[j]=${tmp}
328 changed_something=true
329 fi
330 done
331 done
332 done
333 ${changed_something} || break
334
335 # Make sure we aren't repeating a previous state
336 # First time through, k=1, k/2=0
337 sort_history[k]="${modnums[*]}"
338 if [[ ${sort_history[k]} == ${sort_history[k/2]} ]]; then
339 eerror "Detected an infinite loop sorting modules; blundering ahead"
340 break
341 fi
342 done
343
344 # Finally we sort our modules in number order
345 um=""
346 for (( i=0; i<nmods; i++ )); do
347 um="${um}${modnums[i]} ${MODULES[i]} ${PROVIDES[i]}\n"
348 done
349
350 p=( $( echo -e "${um}" | sort -n | awk '{print $2,$3}' ) )
351 MODULES=()
352 PROVIDES=()
353 j=0
354 for (( i=0; i<${#p[@]}; i+=2 )); do
355 MODULES[j]=${p[i]}
356 PROVIDES[j]=${p[i+1]}
357 (( j++ ))
358 done
359 }
360
361 # bool modules_check_depends(bool showprovides)
362 modules_check_depends() {
363 local showprovides=${1:-false} nmods=${#MODULES[@]} i j needmod
364 local missingdeps p interface=false
365
366 for (( i=0; i<nmods; i++ )); do
367 if [[ $( type -t ${MODULES[i]}_need ) == function ]]; then
368 for needmod in $( ${MODULES[i]}_need ); do
369 missingdeps=true
370 for (( j=0; j<nmods; j++ )); do
371 if [[ ${needmod} == ${MODULES[j]} || ${needmod} == ${PROVIDES[j]} ]]; then
372 missingdeps=false
373 break
374 fi
375 done
376 if ${missingdeps} ; then
377 eerror "${MODULES[i]} needs ${needmod} (dependency failure)"
378 return 1
379 fi
380 done
381 fi
382
383 ${MODULES[i]}_check_depends || return 1
384 [[ ${PROVIDES[i]} == interface ]] && interface=true
385
386 if ${showprovides} ; then
387 [[ ${PROVIDES[i]} != ${MODULES[i]} ]] && veinfo "${MODULES[i]} provides ${PROVIDES[i]}"
388 fi
389 done
390
391 if ! ${interface} ; then
392 eerror "no interface module has been loaded"
393 return 1
394 fi
395
396 return 0
397 }
398
399 # bool modules_load(char *iface, bool starting)
400 #
401 # Loads the defined handler and modules for the interface
402 # Returns 0 on success, otherwise 1
403 modules_load() {
404 local iface=${1} starting=${2:-true} mod p=false i j unsetfuncs
405 local -a x
406 local RC_INDENTATION=${RC_INDENTATION} # so it will reset after function
407 local -a PROVIDES
408
409 if [[ ${iface} == lo ]]; then
410 # We force lo to only use these modules for a major speed boost
411 modules_force=( "iproute2" "ifconfig" )
412 else
413 eval x=( \"\$\{modules_force_${iface}\[@\]\}\" )
414 [[ -n ${x} ]] && modules_force=( "${x[@]}" )
415 if [[ -n ${modules_force} ]]; then
416 ewarn "WARNING: You are forcing modules!"
417 ewarn "Do not complain or file bugs if things start breaking"
418 report=true
419 fi
420 veinfo "Loading networking modules for ${iface}"
421 fi
422 eindent
423
424 if [[ -z ${modules_force} ]]; then
425 modules_load_auto || return 1
426 else
427 j=${#modules_force[@]}
428 for (( i=0; i<j; i++ )); do
429 module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1
430 ${modules_force[i]}_check_installed || unset modules_force[i]
431 done
432 MODULES=( "${modules_force[@]}" )
433 fi
434
435 # We now buffer the _provides functions for a big speed boost
436 j=${#MODULES[@]}
437 for (( i=0; i<j; i++ )); do
438 PROVIDES[i]=$( ${MODULES[i]}_provides )
439 done
440
441 if [[ -z ${modules_force[@]} ]]; then
442 if ${starting}; then
443 modules_check_user || return 1
444 fi
445
446 # We unset unloaded module functions here as so we can error
447 # with a message informing the user to emerge the correct
448 # package if it's in their modules
449 [[ -n ${unsetfuncs} ]] && unset ${unsetfuncs}
450
451 modules_sort
452 fi
453
454 # Setup class wrappers: interface_up -> iproute2_up, for example
455 j=${#MODULES[@]}
456 for (( i=0; i<j; i++ )); do
457 module_class_wrap ${MODULES[i]} ${PROVIDES[i]}
458 done
459
460 modules_check_installed || return 1
461
462 [[ ${iface} != lo ]] && veinfo "modules: ${MODULES[@]}"
463 eindent
464
465 [[ ${iface} != lo && ${starting} == true ]] && p=true
466 modules_check_depends ${p} || return 1
467 return 0
468 }
469
470 # bool iface_start(char *interface)
471 #
472 # iface_start is called from start. It's expected to start the base
473 # interface (for example "eth0"), aliases (for example "eth0:1") and to start
474 # VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by
475 # calling itself recursively.
476 iface_start() {
477 local iface=${1} mod i label config_counter=-1 x conf warn=false inet6
478 local RC_INDENTATION=${RC_INDENTATION} # so it will reset after function
479 local -a config config_fallback
480 local ifvar=$( interface_variable ${iface} )
481
482 # pre Start any modules with
483 for mod in ${MODULES[@]}; do
484 if [[ $( type -t ${mod}_pre_start ) == function ]]; then
485 ${mod}_pre_start ${iface} || { eend 1; return 1; }
486 fi
487 done
488
489 # New style config - one variable fits all
490 eval config=( \"\$\{config_${ifvar}\[@\]\}\" )
491 eval config_fallback=( \"\$\{fallback_${ifvar}\[@\]\}\" )
492
493 # We must support old configs
494 if [[ -z ${config} ]]; then
495 interface_get_old_config ${iface} || return 1
496 fi
497
498 # Provide a default of DHCP if no configuration is set
499 if [[ -z ${config} ]]; then
500 if [[ $( type -t dhcp_start ) == function ]]; then
501 config=( "dhcp" )
502 warn=true
503 else
504 eerror "Cannot default to dhcp as there is no dhcp module loaded"
505 eerror "No configuration for ${iface}"
506 return 1
507 fi
508 fi
509
510 einfo "Bringing up ${iface}"
511 eindent
512 for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do
513 # Null inet address
514 # We do this so we can have an inet6 only setup
515 [[ ${config[config_counter]} == "null" ]] && eend 0 && continue
516
517 ${warn} && ewarn "Configuration not set for ${iface} - assuming dhcp"
518 warn=false
519
520 # We convert it to an array - this has the added
521 # bonus of trimming spaces!
522 conf=( ${config[config_counter]} )
523 einfo "${conf[0]}"
524
525 # Do we have a function for our config?
526 if [[ $( type -t ${conf[0]}_start ) == function ]]; then
527 # Check that the module is valid
528 x=false
529 for mod in ${MODULES[@]}; do
530 if [[ $( ${mod}_provides ) == ${conf[0]} ]]; then
531 x=true
532 break
533 fi
534 done
535
536 if ! ${x}; then
537 [[ $( type -t ${conf[0]}_check_installed == function ) ]] && ${conf[0]}_check_installed true
538 eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)"
539 else
540 eindent
541 ${conf[0]}_start ${iface} ; x=$?
542 eoutdent
543 [[ ${x} == 0 ]] && continue
544 fi
545 # We need to test to see if it's an IP address or a function
546 # We do this by testing if the 1st character is a digit
547 elif [[ ${conf[0]:0:1} == [[:digit:]] ]]; then
548 x=0
549 # if [[ $(type -t address_exists ) == function ]]; then
550 # if address_exists ${iface} ${conf[0]} ; then
551 # eerror "${conf[0]%%/*} already taken on ${iface}"
552 # x=1
553 # fi
554 # fi
555 [[ ${x} == 0 ]] && interface_add_address ${iface} ${conf[@]} ; x=$?
556 eend ${x} && continue
557 else
558 eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)"
559 fi
560
561 if [[ -n ${config_fallback[config_counter]} ]]; then
562 einfo "Trying fallback configuration"
563 config[config_counter]=${config_fallback[config_counter]}
564 config_fallback[label_counter]=''
565 (( config_counter-- )) # since the loop will increment it
566 continue
567 fi
568
569 # Only return failure if it was the first address for the interface
570 [[ ${config_counter} -eq 0 ]] && return 1
571 done
572 eoutdent
573
574 # Start any modules with _post_start
575 for mod in ${MODULES[@]}; do
576 if [[ function == $( type -t ${mod}_post_start ) ]]; then
577 ${mod}_post_start ${iface} || return 1
578 fi
579 done
580
581 return 0
582 }
583
584 # bool iface_stop(char *interface)
585 #
586 # iface_stop: bring down an interface. Don't trust information in
587 # /etc/conf.d/net since the configuration might have changed since
588 # iface_start ran. Instead query for current configuration and bring
589 # down the interface.
590 #
591 # However, we are currently reliant on handler and modules specified
592 # in /etc/conf.d/net
593 iface_stop() {
594 local iface=${1} i aliases need_begin=false mod
595 local RC_INDENTATION=${RC_INDENTATION} # so it will reset after function
596
597 # pre Stop any modules
598 for mod in ${MODULES[@]}; do
599 [[ $( type -t ${mod}_pre_stop ) == function ]] && ${mod}_pre_stop ${iface}
600 done
601
602 einfo "Bringing down ${iface}"
603 eindent
604
605 # Collect list of aliases for this interface.
606 # List will be in reverse order.
607 aliases=$( interface_get_aliases_rev ${iface} )
608
609 # Stop aliases before primary interface.
610 # Note this must be done in reverse order, since ifconfig eth0:1
611 # will remove eth0:2, etc. It might be sufficient to simply remove
612 # the base interface but we're being safe here.
613 for i in ${aliases} ${iface}; do
614 # Stop all our modules
615 for mod in ${MODULES[@]}; do
616 [[ $( type -t ${mod}_stop ) == function ]] && ${mod}_stop ${i}
617 done
618
619 # A module may have removed the interface
620 interface_exists ${iface} || { eend 0; continue; }
621
622 # Delete all the addresses for this alias
623 interface_del_addresses ${i}
624
625 # Do final shut down of this alias
626 ebegin "Shutting down ${i}"
627 interface_iface_stop ${i}
628 eend $?
629 done
630
631 # post Stop any modules
632 for mod in ${MODULES[@]}; do
633 # We have already taken down the interface, so no need to error
634 [[ $( type -t ${mod}_post_stop ) == function ]] && ${mod}_post_stop ${iface}
635 done
636
637 return 0
638 }
639
640 # bool run_start(char *iface)
641 #
642 # Brings up ${IFACE}. Calls preup, iface_start, then postup.
643 # Returns 0 (success) unless preup or iface_start returns 1 (failure).
644 # Ignores the return value from postup.
645 # We cannot check that the device exists ourselves as modules like
646 # tuntap make create it.
647 run_start() {
648 local iface=${1} ifvar x
649
650 if [[ ${iface} == lo ]]; then
651 ebegin "Bringing up ${iface}"
652 interface_loopback_create
653 eend $?
654 return $?
655 fi
656
657 # We may not have a loaded module for ${iface}
658 # Some users may have "alias natsemi eth0" in /etc/modules.d/foo
659 # so we can work with this
660 # However, if they do the same with eth1 and try to start it
661 # but eth0 has not been loaded then the module gets loaded as
662 # eth0.
663 # Not much we can do about this :(
664 ! interface_exists ${iface} && /sbin/modprobe ${iface} &>/dev/null
665
666 # Setup variables for pre/post to use
667 ifvar=$( interface_variable ${iface} )
668 local IFACE=${iface} IFVAR=${ifvar}
669
670 # Call user-defined preup function if it exists
671 if [[ $( type -t preup ) == function ]]; then
672 einfo "Running preup function"
673 eindent
674 preup ${iface} ; x=$?
675 eoutdent
676 if [[ ${x} != 0 ]]; then
677 eerror "preup ${iface} failed"
678 return 1
679 fi
680 fi
681
682 # Don't let preup modify us
683 iface=${1}
684 local IFACE=${iface} IFVAR=${ifvar}
685
686 # Start the interface
687 if ! iface_start ${iface} ; then
688 interface_down ${iface}
689 eend 1
690 return 1
691 fi
692
693
694 # Call user-defined postup function if it exists
695 if [[ $( type -t postup ) == function ]]; then
696 einfo "Running postup function"
697 eindent
698 postup ${iface}
699 eoutdent
700 fi
701
702 return 0
703 }
704
705 # bool run_stop(char *iface) {
706 #
707 # Brings down ${iface}. If predown call returns non-zero, then
708 # stop returns non-zero to indicate failure bringing down device.
709 # In all other cases stop returns 0 to indicate success.
710 run_stop() {
711 local iface=${1} ifvar x
712
713 # Don't run any special shutdown functions for lo
714 if [[ ${iface} == lo ]]; then
715 ebegin "Shutting down ${iface}"
716 interface_iface_stop ${iface}
717 eend $?
718 return 0
719 fi
720
721 # Setup variables for pre/post to use
722 ifvar=$( interface_variable ${iface} )
723 local IFACE=${iface} IFVAR=${ifvar}
724
725 # Call user-defined predown function if it exists
726 if [[ $( type -t predown ) == function ]]; then
727 einfo "Running predown function"
728 eindent
729 predown ${iface} ; x=$?
730 eoutdent
731 if [[ ${x} != 0 ]]; then
732 eend 1 "predown ${iface} failed"
733 return 1
734 fi
735 elif is_net_fs /; then
736 eerror "root filesystem is network mounted -- can't stop ${iface}"
737 return 1
738 fi
739
740 # Don't let predown modify us
741 iface=${1}
742 local IFACE=${iface} IFVAR=${ifvar}
743
744 iface_stop ${iface} || return 1 # always succeeds, btw
745
746 # Call user-defined postdown function if it exists
747 if [[ $( type -t postdown ) == function ]]; then
748 einfo "Running postdown function"
749 eindent
750 postdown ${iface}
751 eoutdent
752 fi
753
754 return 0
755 }
756
757 # bool run(char *iface, char *cmd)
758 #
759 # Main start/stop entry point
760 # We load modules here and remove any functions that they
761 # added as we may be called inside the same shell scope for another interface
762 run() {
763 local iface=${1} cmd=${2} r=1 RC_INDENTATION=${RC_INDENTATION} # so it will reset after function
764 local before starting=true
765 local -a MODULES mods
766
767 eindent
768
769 unset_functions=${unset_functions:-false}
770 ${unset_functions} && before="$( typeset -F )"
771 [[ ${cmd} == "stop" ]] && starting=false
772 if modules_load ${iface} ${starting} ; then
773 if [[ ${cmd} == "stop" ]]; then
774 # Reverse the module list for stopping
775 mods=( "${MODULES[@]}" )
776 for ((i = 0; i < ${#mods[@]}; i++)); do
777 MODULES[i]=${mods[((${#mods[@]} - i - 1))]}
778 done
779
780 run_stop ${iface} && r=0
781 else
782 run_start ${iface} && r=0
783 fi
784 fi
785
786 # We need to remove added functions before we quit as other init
787 # scripts may be launching afterwards
788 ${unset_functions} && \
789 unset $( diff -U0 <( echo "${before}" ) <( echo "$( typeset -F )" ) 2>/dev/null \
790 | awk 'BEGIN { ORS = " "; } /+declare -f/ { print $3; }' ) 2>/dev/null
791
792 return ${r}
793 }
794
795 # bool start(void)
796 #
797 # Start entry point so that we only have one function
798 # which localises variables and unsets functions
799 start() {
800 einfo "Starting ${IFACE}"
801 run ${IFACE} start
802 return $?
803 }
804
805 # bool stop(void)
806 #
807 # Stop entry point so that we only have one function
808 # which localises variables and unsets functions
809 stop() {
810 einfo "Stopping ${IFACE}"
811 run ${IFACE} stop
812 return $?
813 }
814
815 # bool restart(void)
816 #
817 # Restart entry point
818 # We do this so as we only have to remove functions when stopping
819 restart() {
820 local unset_functions=true
821 service_started "${myservice}" && svc_stop
822 unset_functions=false
823 svc_start
824 return $?
825 }
826
827 # 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