/[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 838 - (show annotations) (download)
Wed Jan 12 14:25:18 2005 UTC (9 years, 9 months ago) by uberlord
File size: 24094 byte(s)
net.lo now ignores dot files when loading modules

1 #!/sbin/runscript
2 # net-scripts main code
3 # Version 1.0.6
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 ! -name ".*" | 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 # Handle "noop" correctly
499 if [[ ${config[0]} == "noop" ]]; then
500 if interface_is_up ${iface} true ; then
501 einfo "Keeping current configuration for ${iface}"
502 eend 0
503 return 0
504 fi
505
506 # Remove noop from the config var
507 config=( "${config[@]:1}" )
508 fi
509
510 # Provide a default of DHCP if no configuration is set
511 if [[ -z ${config} ]]; then
512 if [[ $( type -t dhcp_start ) == function ]]; then
513 config=( "dhcp" )
514 warn=true
515 else
516 eerror "Cannot default to dhcp as there is no dhcp module loaded"
517 eerror "No configuration for ${iface}"
518 return 1
519 fi
520 fi
521
522 einfo "Bringing up ${iface}"
523 eindent
524 for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do
525 # Null inet address
526 # We do this so we can have an inet6 only setup
527 [[ ${config[config_counter]} == "null" \
528 || ${config[config_counter]} == "noop" ]] && eend 0 && continue
529
530 ${warn} && ewarn "Configuration not set for ${iface} - assuming dhcp"
531 warn=false
532
533 # We convert it to an array - this has the added
534 # bonus of trimming spaces!
535 conf=( ${config[config_counter]} )
536 einfo "${conf[0]}"
537
538 # Do we have a function for our config?
539 if [[ $( type -t ${conf[0]}_start ) == function ]]; then
540 # Check that the module is valid
541 x=false
542 for mod in ${MODULES[@]}; do
543 if [[ $( ${mod}_provides ) == ${conf[0]} ]]; then
544 x=true
545 break
546 fi
547 done
548
549 if ! ${x}; then
550 [[ $( type -t ${conf[0]}_check_installed == function ) ]] && ${conf[0]}_check_installed true
551 eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)"
552 else
553 eindent
554 ${conf[0]}_start ${iface} ; x=$?
555 eoutdent
556 [[ ${x} == 0 ]] && continue
557 fi
558 # We need to test to see if it's an IP address or a function
559 # We do this by testing if the 1st character is a digit
560 elif [[ ${conf[0]:0:1} == [[:digit:]] ]]; then
561 x=0
562 # if [[ $(type -t address_exists ) == function ]]; then
563 # if address_exists ${iface} ${conf[0]} ; then
564 # eerror "${conf[0]%%/*} already taken on ${iface}"
565 # x=1
566 # fi
567 # fi
568 [[ ${x} == 0 ]] && interface_add_address ${iface} ${conf[@]} ; x=$?
569 eend ${x} && continue
570 else
571 eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)"
572 fi
573
574 if [[ -n ${config_fallback[config_counter]} ]]; then
575 einfo "Trying fallback configuration"
576 config[config_counter]=${config_fallback[config_counter]}
577 config_fallback[label_counter]=''
578 (( config_counter-- )) # since the loop will increment it
579 continue
580 fi
581
582 # Only return failure if it was the first address for the interface
583 [[ ${config_counter} -eq 0 ]] && return 1
584 done
585 eoutdent
586
587 # Start any modules with _post_start
588 for mod in ${MODULES[@]}; do
589 if [[ function == $( type -t ${mod}_post_start ) ]]; then
590 ${mod}_post_start ${iface} || return 1
591 fi
592 done
593
594 return 0
595 }
596
597 # bool iface_stop(char *interface)
598 #
599 # iface_stop: bring down an interface. Don't trust information in
600 # /etc/conf.d/net since the configuration might have changed since
601 # iface_start ran. Instead query for current configuration and bring
602 # down the interface.
603 #
604 # However, we are currently reliant on handler and modules specified
605 # in /etc/conf.d/net
606 iface_stop() {
607 local iface=${1} i aliases need_begin=false mod
608 local RC_INDENTATION=${RC_INDENTATION} # so it will reset after function
609
610 # pre Stop any modules
611 for mod in ${MODULES[@]}; do
612 [[ $( type -t ${mod}_pre_stop ) == function ]] && ${mod}_pre_stop ${iface}
613 done
614
615 einfo "Bringing down ${iface}"
616 eindent
617
618 # Collect list of aliases for this interface.
619 # List will be in reverse order.
620 aliases=$( interface_get_aliases_rev ${iface} )
621
622 # Stop aliases before primary interface.
623 # Note this must be done in reverse order, since ifconfig eth0:1
624 # will remove eth0:2, etc. It might be sufficient to simply remove
625 # the base interface but we're being safe here.
626 for i in ${aliases} ${iface}; do
627 # Stop all our modules
628 for mod in ${MODULES[@]}; do
629 [[ $( type -t ${mod}_stop ) == function ]] && ${mod}_stop ${i}
630 done
631
632 # A module may have removed the interface
633 interface_exists ${iface} || { eend 0; continue; }
634
635 # Delete all the addresses for this alias
636 interface_del_addresses ${i}
637
638 # Do final shut down of this alias
639 ebegin "Shutting down ${i}"
640 interface_iface_stop ${i}
641 eend $?
642 done
643
644 # post Stop any modules
645 for mod in ${MODULES[@]}; do
646 # We have already taken down the interface, so no need to error
647 [[ $( type -t ${mod}_post_stop ) == function ]] && ${mod}_post_stop ${iface}
648 done
649
650 return 0
651 }
652
653 # bool run_start(char *iface)
654 #
655 # Brings up ${IFACE}. Calls preup, iface_start, then postup.
656 # Returns 0 (success) unless preup or iface_start returns 1 (failure).
657 # Ignores the return value from postup.
658 # We cannot check that the device exists ourselves as modules like
659 # tuntap make create it.
660 run_start() {
661 local iface=${1} ifvar x
662
663 if [[ ${iface} == lo ]]; then
664 ebegin "Bringing up ${iface}"
665 interface_loopback_create
666 eend $?
667 return $?
668 fi
669
670 # We may not have a loaded module for ${iface}
671 # Some users may have "alias natsemi eth0" in /etc/modules.d/foo
672 # so we can work with this
673 # However, if they do the same with eth1 and try to start it
674 # but eth0 has not been loaded then the module gets loaded as
675 # eth0.
676 # Not much we can do about this :(
677 if ! interface_exists ${iface} ; then
678 if ! /sbin/modprobe ${iface} &>/dev/null ; then
679 eerror "${iface} does not exist"
680 return 1
681 fi
682 fi
683
684 # Setup variables for pre/post to use
685 ifvar=$( interface_variable ${iface} )
686 local IFACE=${iface} IFVAR=${ifvar}
687
688 # Call user-defined preup function if it exists
689 if [[ $( type -t preup ) == function ]]; then
690 einfo "Running preup function"
691 eindent
692 preup ${iface} ; x=$?
693 eoutdent
694 if [[ ${x} != 0 ]]; then
695 eerror "preup ${iface} failed"
696 return 1
697 fi
698 fi
699
700 # Don't let preup modify us
701 iface=${1}
702 local IFACE=${iface} IFVAR=${ifvar} config
703
704 # If config is set to noop and the interface is up with an address
705 # then we don't start it
706 eval config=( \"\$\{config_${ifvar}\[@\]\}\" )
707 if [[ ${config[0]} == "noop" ]] && interface_is_up ${iface} true ; then
708 einfo "Keeping current configuration for ${iface}"
709 eend 0
710 else
711 # Remove noop from the config var
712 [[ ${config[0]} == "noop" ]] && eval "config_${ifvar}=( "\"\$\{config\[@\]:1\}\"" )"
713
714 # There may be existing ip address info - so we strip it
715 interface_del_addresses ${iface}
716
717 # Start the interface
718 if ! iface_start ${iface} ; then
719 interface_down ${iface}
720 eend 1
721 return 1
722 fi
723 fi
724
725 # Call user-defined postup function if it exists
726 if [[ $( type -t postup ) == function ]]; then
727 einfo "Running postup function"
728 eindent
729 postup ${iface}
730 eoutdent
731 fi
732
733 return 0
734 }
735
736 # bool run_stop(char *iface) {
737 #
738 # Brings down ${iface}. If predown call returns non-zero, then
739 # stop returns non-zero to indicate failure bringing down device.
740 # In all other cases stop returns 0 to indicate success.
741 run_stop() {
742 local iface=${1} ifvar x
743
744 # Don't run any special shutdown functions for lo
745 if [[ ${iface} == lo ]]; then
746 ebegin "Shutting down ${iface}"
747 interface_iface_stop ${iface}
748 eend $?
749 return 0
750 fi
751
752 # Setup variables for pre/post to use
753 ifvar=$( interface_variable ${iface} )
754 local IFACE=${iface} IFVAR=${ifvar}
755
756 # Call user-defined predown function if it exists
757 if [[ $( type -t predown ) == function ]]; then
758 einfo "Running predown function"
759 eindent
760 predown ${iface} ; x=$?
761 eoutdent
762 if [[ ${x} != 0 ]]; then
763 eend 1 "predown ${iface} failed"
764 return 1
765 fi
766 elif is_net_fs /; then
767 eerror "root filesystem is network mounted -- can't stop ${iface}"
768 return 1
769 fi
770
771 # Don't let predown modify us
772 iface=${1}
773 local IFACE=${iface} IFVAR=${ifvar}
774
775 iface_stop ${iface} || return 1 # always succeeds, btw
776
777 # Call user-defined postdown function if it exists
778 if [[ $( type -t postdown ) == function ]]; then
779 einfo "Running postdown function"
780 eindent
781 postdown ${iface}
782 eoutdent
783 fi
784
785 return 0
786 }
787
788 # bool run(char *iface, char *cmd)
789 #
790 # Main start/stop entry point
791 # We load modules here and remove any functions that they
792 # added as we may be called inside the same shell scope for another interface
793 run() {
794 local iface=${1} cmd=${2} r=1 RC_INDENTATION=${RC_INDENTATION} # so it will reset after function
795 local before starting=true
796 local -a MODULES mods
797
798 eindent
799
800 unset_functions=${unset_functions:-false}
801 ${unset_functions} && before="$( typeset -F )"
802 [[ ${cmd} == "stop" ]] && starting=false
803 if modules_load ${iface} ${starting} ; then
804 if [[ ${cmd} == "stop" ]]; then
805 # Reverse the module list for stopping
806 mods=( "${MODULES[@]}" )
807 for ((i = 0; i < ${#mods[@]}; i++)); do
808 MODULES[i]=${mods[((${#mods[@]} - i - 1))]}
809 done
810
811 run_stop ${iface} && r=0
812 else
813 run_start ${iface} && r=0
814 fi
815 fi
816
817 # We need to remove added functions before we quit as other init
818 # scripts may be launching afterwards
819 ${unset_functions} && \
820 unset $( diff -U0 <( echo "${before}" ) <( echo "$( typeset -F )" ) 2>/dev/null \
821 | awk 'BEGIN { ORS = " "; } /+declare -f/ { print $3; }' ) 2>/dev/null
822
823 return ${r}
824 }
825
826 # bool start(void)
827 #
828 # Start entry point so that we only have one function
829 # which localises variables and unsets functions
830 start() {
831 einfo "Starting ${IFACE}"
832 run ${IFACE} start
833 return $?
834 }
835
836 # bool stop(void)
837 #
838 # Stop entry point so that we only have one function
839 # which localises variables and unsets functions
840 stop() {
841 einfo "Stopping ${IFACE}"
842 run ${IFACE} stop
843 return $?
844 }
845
846 # bool restart(void)
847 #
848 # Restart entry point
849 # We do this so as we only have to remove functions when stopping
850 restart() {
851 local unset_functions=true
852 service_started "${myservice}" && svc_stop
853 unset_functions=false
854 svc_start
855 return $?
856 }
857
858 # 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