/[vps]/baselayout-vserver/trunk/net-scripts/init.d/net.lo
Gentoo

Contents of /baselayout-vserver/trunk/net-scripts/init.d/net.lo

Parent Directory Parent Directory | Revision Log Revision Log


Revision 236 - (show annotations) (download)
Tue Feb 14 13:00:44 2006 UTC (9 years ago) by phreak
File size: 27379 byte(s)
Merging r1881
1 #!/sbin/runscript
2 # Copyright (c) 2004-2006 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4
5 # Contributed by Roy Marples (uberlord@gentoo.org)
6 # Many thanks to Aron Griffis (agriffis@gentoo.org)
7 # for help, ideas and patches
8
9 #NB: Config is in /etc/conf.d/net
10
11 # For pcmcia users. note that pcmcia must be added to the same
12 # runlevel as the net.* script that needs it.
13 depend() {
14 need localmount
15 use isapnp isdn pcmcia usb wlan
16
17 # Load any custom depend functions for the given interface
18 # For example, br0 may need eth0 and eth1
19 local iface="${myservice#*.}"
20 [[ $(type -t "depend_${iface}") == "function" ]] && depend_${iface}
21
22 return 0
23 }
24
25 # Define where our modules are
26 MODULES_DIR="${svclib}/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 MODULE will be set.
33 after() {
34 eval "${MODULE}_after() { echo \"$*\"; }"
35 }
36 before() {
37 eval "${MODULE}_before() { echo \"$*\"; }"
38 }
39 need() {
40 eval "${MODULE}_need() { echo \"$*\"; }"
41 }
42 installed() {
43 # We deliberately misspell this as _installed will probably be used
44 # at some point
45 eval "${MODULE}_instlled() { echo \"$*\"; }"
46 }
47 provide() {
48 eval "${MODULE}_provide() { echo \"$*\"; }"
49 }
50 functions() {
51 eval "${MODULE}_functions() { echo \"$*\"; }"
52 }
53 variables() {
54 eval "${MODULE}_variables() { echo \"$*\"; }"
55 }
56
57 # bool module_load_minimum(char *module)
58 #
59 # Does the minimum checking on a module - even when forcing
60 module_load_minimum() {
61 local f="$1" MODULE="${1##*/}"
62
63 if [[ ! -f ${f} ]] ; then
64 eerror "${f} does not exist"
65 return 1
66 fi
67
68 if ! source "${f}" ; then
69 eerror "${MODULE} failed a sanity check"
70 return 1
71 fi
72
73 for f in depend; do
74 is_function "${MODULE}_${f}" && continue
75 eerror "${MODULE} does not support the required function ${f}"
76 return 1
77 done
78
79 return 0
80 }
81
82 # bool modules_load_auto()
83 #
84 # Load and check each module for sanity
85 # If the module is not installed, the functions are to be removed
86 modules_load_auto() {
87 local i j inst
88
89 # Populate the MODULES array
90 # Basically we treat evey file in ${MODULES_DIR} as a module
91 MODULES=( $( cd "${MODULES_DIR}" ; ls ) )
92 j="${#MODULES[@]}"
93 for (( i=0; i<j; i++ )); do
94 MODULES[i]="${MODULES_DIR}/${MODULES[i]}"
95 [[ ! -f ${MODULES[i]} ]] && unset MODULES[i]
96 done
97 MODULES=( "${MODULES[@]}" )
98
99 # Each of these sources into the global namespace, so it's
100 # important that module functions and variables are prefixed with
101 # the module name, for example iproute2_
102
103 j="${#MODULES[@]}"
104 loaded_interface=false
105 for (( i=0; i<j; i++ )); do
106 if [[ ${MODULES[i]##*/} == "interface" ]] ; then
107 eerror "interface is a reserved name - cannot load a module called interface"
108 return 1
109 fi
110
111 (
112 u=0;
113 module_load_minimum "${MODULES[i]}" || u=1;
114 if [[ ${u} == 0 ]] ; then
115 inst="${MODULES[i]##*/}_check_installed";
116 if is_function "${inst}" ; then
117 ${inst} false || u=1;
118 fi
119 fi
120 exit "${u}";
121 )
122
123 if [[ $? == 0 ]] ; then
124 source "${MODULES[i]}"
125 MODULES[i]="${MODULES[i]##*/}"
126 else
127 unset MODULES[i]
128 fi
129 done
130
131 MODULES=( "${MODULES[@]}" )
132 return 0
133 }
134
135 # bool modules_check_installed(void)
136 #
137 # Ensure that all modules have the required modules loaded
138 # This enables us to remove modules from the MODULES array
139 # Whilst other modules can still explicitly call them
140 # One example of this is essidnet which configures network
141 # settings for the specific ESSID connected to as the user
142 # may be using a daemon to configure wireless instead of our
143 # iwconfig module
144 modules_check_installed() {
145 local i j missingdeps nmods="${#MODULES[@]}"
146
147 for (( i=0; i<nmods; i++ )); do
148 is_function "${MODULES[i]}_instlled" || continue
149 for j in $( ${MODULES[i]}_instlled ); do
150 missingdeps=true
151 if is_function "${j}_check_installed" ; then
152 ${j}_check_installed && missingdeps=false
153 elif is_function "${j}_depend" ; then
154 missingdeps=false
155 fi
156 ${missingdeps} && unset MODULES[i] && unset PROVIDES[i] && break
157 done
158 done
159
160 MODULES=( "${MODULES[@]}" )
161 PROVIDES=( "${PROVIDES[@]}" )
162 }
163
164 # bool modules_check_user(void)
165 modules_check_user() {
166 local iface="$1" ifvar="$(bash_variable "${IFACE}")"
167 local i j k l nmods="${#MODULES[@]}"
168 local -a umods
169
170 # Has the interface got any specific modules?
171 umods="modules_${ifvar}[@]"
172 umods=( "${!umods}" )
173
174 # Global setting follows interface-specific setting
175 umods=( "${umods[@]}" "${modules[@]}" )
176
177 # Add our preferred modules
178 local -a pmods=( "iproute2" "dhcpcd" "iwconfig" "netplugd" )
179 umods=( "${umods[@]}" "${pmods[@]}" )
180
181 # First we strip any modules that conflict from user settings
182 # So if the user specifies pump then we don't use dhcpcd
183 for (( i=0; i<${#umods[@]}; i++ )); do
184 # Some users will inevitably put "dhcp" in their modules
185 # list. To keep users from screwing up their system this
186 # way, ignore this setting so that the default dhcp
187 # module will be used.
188 [[ ${umods[i]} == "dhcp" ]] && continue
189
190 # We remove any modules we explicitly don't want
191 if [[ ${umods[i]} == "!"* ]] ; then
192 for (( j=0; j<nmods; j++ )); do
193 [[ -z ${MODULES[j]} ]] && continue
194 if [[ ${umods[i]:1} == "${MODULES[j]}" \
195 || ${umods[i]:1} == "${PROVIDES[j]}" ]] ; then
196 # We may need to setup a class wrapper for it even though
197 # we don't use it directly
198 # However, we put it into an array and wrap later as
199 # another module may provide the same thing
200 ${MODULES[j]}_check_installed \
201 && WRAP_MODULES=(
202 "${WRAP_MODULES[@]}"
203 "${MODULES[j]} ${PROVIDES[j]}"
204 )
205 unset MODULES[j]
206 unset PROVIDES[j]
207 fi
208 done
209 continue
210 fi
211
212 if ! is_function "${umods[i]}_depend" ; then
213 # If the module is one of our preferred modules, then
214 # ignore this error; whatever is available will be
215 # used instead.
216 (( i < ${#umods[@]} - ${#pmods[@]} )) || continue
217
218 # The function may not exist because the modules software is
219 # not installed. Load the module and report its error
220 if [[ -e "${MODULES_DIR}/${umods[i]}" ]] ; then
221 source "${MODULES_DIR}/${umods[i]}"
222 is_function "${umods[i]}_check_installed" \
223 && ${umods[i]}_check_installed true
224 else
225 eerror "The module \"${umods[i]}\" does not exist"
226 fi
227 return 1
228 fi
229
230 if is_function "${umods[i]}_provide" ; then
231 mod="$(${umods[i]}_provide )"
232 else
233 mod="${umods[i]}"
234 fi
235 for (( j=0; j<nmods; j++ )); do
236 [[ -z ${MODULES[j]} ]] && continue
237 if [[ ${PROVIDES[j]} == "${mod}" && ${umods[i]} != "${MODULES[j]}" ]] ; then
238 # We don't have a match - now ensure that we still provide an
239 # alternative. This is to handle our preferred modules.
240 for (( l=0; l<nmods; l++ )); do
241 [[ ${l} == "${j}" || -z ${MODULES[l]} ]] && continue
242 if [[ ${PROVIDES[l]} == "${mod}" ]] ; then
243 unset MODULES[j]
244 unset PROVIDES[j]
245 break
246 fi
247 done
248 fi
249 done
250 done
251
252 # Then we strip conflicting modules.
253 # We only need to do this for 3rd party modules that conflict with
254 # our own modules and the preferred list AND the user modules
255 # list doesn't specify a preference.
256 for (( i=0; i<nmods-1; i++ )); do
257 [[ -z ${MODULES[i]} ]] && continue
258 for (( j=i+1; j<nmods; j++)); do
259 [[ -z ${MODULES[j]} ]] && continue
260 [[ ${PROVIDES[i]} == "${PROVIDES[j]}" ]] \
261 && unset MODULES[j] && unset PROVIDES[j]
262 done
263 done
264
265 MODULES=( "${MODULES[@]}" )
266 PROVIDES=( "${PROVIDES[@]}" )
267 return 0
268 }
269
270 # void modules_sort(void)
271 #
272 # Sort our modules
273 modules_sort() {
274 local i j nmods=${#MODULES[@]} m
275 local -a provide=() provide_list=() after=() dead=() sorted=() sortedp=()
276
277 # Make our provide list
278 for ((i=0; i<nmods; i++)); do
279 dead[i]="false"
280 if [[ ${MODULES[i]} != "${PROVIDES[i]}" ]] ; then
281 local provided=false
282 for ((j=0; j<${#provide[@]}; j++)); do
283 if [[ ${provide[j]} == "${PROVIDES[i]}" ]] ; then
284 provide_list[j]="${provide_list[j]} ${MODULES[i]}"
285 provided=true
286 fi
287 done
288 if ! ${provided}; then
289 provide[j]="${PROVIDES[i]}"
290 provide_list[j]="${MODULES[i]}"
291 fi
292 fi
293 done
294
295 # Create an after array, which holds which modules the module at
296 # index i must be after
297 for ((i=0; i<nmods; i++)); do
298 if is_function "${MODULES[i]}_after" ; then
299 after[i]=" ${after[i]} $(${MODULES[i]}_after) "
300 fi
301 if is_function "${MODULES[i]}_before" ; then
302 for m in $(${MODULES[i]}_before); do
303 for ((j=0; j<nmods; j++)) ; do
304 if [[ ${PROVIDES[j]} == "${m}" ]] ; then
305 after[j]=" ${after[j]} ${MODULES[i]} "
306 break
307 fi
308 done
309 done
310 fi
311 done
312
313 # Replace the after list modules with real modules
314 for ((i=0; i<nmods; i++)); do
315 if [[ -n ${after[i]} ]] ; then
316 for ((j=0; j<${#provide[@]}; j++)); do
317 after[i]="${after[i]// ${provide[j]} / ${provide_list[j]} }"
318 done
319 fi
320 done
321
322 # We then use the below code to provide a topologial sort
323 module_after_visit() {
324 local name=$1 i x
325
326 for ((i=0; i<nmods; i++)); do
327 [[ ${MODULES[i]} == "$1" ]] && break
328 done
329
330 ${dead[i]} && return
331 dead[i]="true"
332
333 for x in ${after[i]} ; do
334 module_after_visit "${x}"
335 done
336
337 sorted=( "${sorted[@]}" "${MODULES[i]}" )
338 sortedp=( "${sortedp[@]}" "${PROVIDES[i]}" )
339 }
340
341 for x in ${MODULES[@]}; do
342 module_after_visit "${x}"
343 done
344
345 MODULES=( "${sorted[@]}" )
346 PROVIDES=( "${sortedp[@]}" )
347 }
348
349 # bool modules_check_depends(bool showprovides)
350 modules_check_depends() {
351 local showprovides="${1:-false}" nmods="${#MODULES[@]}" i j needmod
352 local missingdeps p interface=false
353
354 for (( i=0; i<nmods; i++ )); do
355 if is_function "${MODULES[i]}_need" ; then
356 for needmod in $( ${MODULES[i]}_need ); do
357 missingdeps=true
358 for (( j=0; j<nmods; j++ )); do
359 if [[ ${needmod} == "${MODULES[j]}" \
360 || ${needmod} == "${PROVIDES[j]}" ]] ; then
361 missingdeps=false
362 break
363 fi
364 done
365 if ${missingdeps} ; then
366 eerror "${MODULES[i]} needs ${needmod} (dependency failure)"
367 return 1
368 fi
369 done
370 fi
371
372 if is_function "${MODULES[i]}_functions" ; then
373 for f in $( ${MODULES[i]}_functions ); do
374 if ! is_function "${f}" ; then
375 eerror "${MODULES[i]}: missing required function \"${f}\""
376 return 1
377 fi
378 done
379 fi
380
381 [[ ${PROVIDES[i]} == "interface" ]] && interface=true
382
383 if ${showprovides} ; then
384 [[ ${PROVIDES[i]} != "${MODULES[i]}" ]] \
385 && veinfo "${MODULES[i]} provides ${PROVIDES[i]}"
386 fi
387 done
388
389 if ! ${interface} ; then
390 eerror "no interface module has been loaded"
391 return 1
392 fi
393
394 return 0
395 }
396
397 # bool modules_load(char *iface, bool starting)
398 #
399 # Loads the defined handler and modules for the interface
400 # Returns 0 on success, otherwise 1
401 modules_load() {
402 local iface="$1" starting="${2:-true}" MODULE p=false i j k
403 local -a x
404 local RC_INDENTATION="${RC_INDENTATION}"
405 local -a PROVIDES WRAP_MODULES
406
407 if [[ ${iface} != "lo" ]] ; then
408 x="modules_force_${iface}[@]"
409 [[ -n ${!x} ]] && modules_force=( "${!x}" )
410 if [[ -n ${modules_force} ]] ; then
411 ewarn "WARNING: You are forcing modules!"
412 ewarn "Do not complain or file bugs if things start breaking"
413 report=true
414 fi
415 fi
416
417 veinfo "Loading networking modules for ${iface}"
418 eindent
419
420 if [[ -z ${modules_force} ]] ; then
421 modules_load_auto || return 1
422 else
423 j="${#modules_force[@]}"
424 for (( i=0; i<j; i++ )); do
425 module_load_minimum "${MODULES_DIR}/${modules_force[i]}" || return 1
426 if is_function "${modules_force[i]}_check_installed" ; then
427 ${modules_force[i]}_check_installed || unset modules_force[i]
428 fi
429 done
430 MODULES=( "${modules_force[@]}" )
431 fi
432
433 j="${#MODULES[@]}"
434 for (( i=0; i<j; i++ )); do
435 # Now load our dependencies - we need to use the MODULE variable
436 # here as the after/before/need functions use it
437 MODULE="${MODULES[i]}"
438 ${MODULE}_depend
439
440 # If no provide is given, assume module name
441 if is_function "${MODULES[i]}_provide" ; then
442 PROVIDES[i]="$(${MODULES[i]}_provide)"
443 else
444 PROVIDES[i]="${MODULES[i]}"
445 fi
446 done
447
448 if [[ -n ${modules_force[@]} ]] ; then
449 # Strip any duplicate modules providing the same thing
450 j="${#MODULES[@]}"
451 for (( i=0; i<j-1; i++ )); do
452 [[ -z ${MODULES[i]} ]] && continue
453 for (( k=i+1; k<j; k++ )); do
454 if [[ ${PROVIDES[i]} == ${PROVIDES[k]} ]] ; then
455 unset MODULES[k]
456 unset PROVIDES[k]
457 fi
458 done
459 done
460 MODULES=( "${MODULES[@]}" )
461 PROVIDES=( "${PROVIDES[@]}" )
462 else
463 if ${starting}; then
464 modules_check_user "${iface}" || return 1
465 else
466 # Always prefer iproute2 for taking down interfaces
467 if is_function iproute2_provide ; then
468 function_wrap iproute2 "$(iproute2_provide)"
469 fi
470 fi
471 fi
472
473 # Wrap our modules
474 j="${#MODULES[@]}"
475 for (( i=0; i<j; i++ )); do
476 function_wrap "${MODULES[i]}" "${PROVIDES[i]}"
477 done
478 j="${#WRAP_MODULES[@]}"
479 for (( i=0; i<j; i++ )); do
480 function_wrap ${WRAP_MODULES[i]}
481 done
482
483 if [[ -z ${modules_force[@]} ]] ; then
484 modules_check_installed || return 1
485 modules_sort || return 1
486 fi
487
488 veinfo "modules: ${MODULES[@]}"
489 eindent
490
491 ${starting} && p=true
492 modules_check_depends "${p}" || return 1
493 return 0
494 }
495
496 # bool iface_start(char *interface)
497 #
498 # iface_start is called from start. It's expected to start the base
499 # interface (for example "eth0"), aliases (for example "eth0:1") and to start
500 # VLAN interfaces (for example eth0.0, eth0.1). VLAN setup is accomplished by
501 # calling itself recursively.
502 iface_start() {
503 local iface="$1" mod config_counter="-1" x config_worked=false
504 local RC_INDENTATION="${RC_INDENTATION}"
505 local -a config fallback fallback_route conf a b
506 local ifvar=$( bash_variable "$1" ) i j
507
508 # Try and work out a metric for the interface if we're on auto
509 x="metric_${ifvar}"
510 if [[ -z ${!x} ]] ; then
511 if [[ ${RC_AUTO_INTERFACE} == "yes" ]] ; then
512 eval "metric_${ifvar}=\"$(calculate_metric ${iface})\""
513 else
514 eval "metric_${ifvar}=0"
515 fi
516 fi
517
518 # pre Start any modules with
519 for mod in ${MODULES[@]}; do
520 if is_function "${mod}_pre_start" ; then
521 ${mod}_pre_start "${iface}" || { eend 1; return 1; }
522 fi
523 done
524
525 # We now expand the configuration parameters and pray that the
526 # fallbacks expand to the same number as config or there will be
527 # trouble!
528 a="config_${ifvar}[@]"
529 a=( "${!a}" )
530 for (( i=0; i<${#a[@]}; i++ )); do
531 eval b=( $(expand_parameters "${a[i]}") )
532 config=( "${config[@]}" "${b[@]}" )
533 done
534
535 a="fallback_${ifvar}[@]"
536 a=( "${!a}" )
537 for (( i=0; i<${#a[@]}; i++ )); do
538 eval b=( $(expand_parameters "${a[i]}") )
539 fallback=( "${fallback[@]}" "${b[@]}" )
540 done
541
542 # We don't expand routes
543 fallback_route="fallback_route_${ifvar}[@]"
544 fallback_route=( "${!fallback_route}" )
545
546 # We must support old configs
547 if [[ -z ${config} ]] ; then
548 interface_get_old_config "${iface}" || return 1
549 if [[ -n ${config} ]] ; then
550 ewarn "You are using a depreciated configuration syntax for ${iface}"
551 ewarn "You are advised to read /etc/conf.d/net.example and upgrade it accordingly"
552 fi
553 fi
554
555 # Handle "noop" correctly
556 if [[ ${config[0]} == "noop" ]] ; then
557 if interface_is_up "${iface}" true ; then
558 einfo "Keeping current configuration for ${iface}"
559 eend 0
560 return 0
561 fi
562
563 # Remove noop from the config var
564 config=( "${config[@]:1}" )
565 fi
566
567 # Provide a default of DHCP if no configuration is set and we're auto
568 # Otherwise a default of NULL
569 if [[ -z ${config} ]] ; then
570 # if [[ ${RC_AUTO_INTERFACE} == "yes" ]] ; then
571 ewarn "Configuration not set for ${iface} - assuming DHCP"
572 if is_function "dhcp_start" ; then
573 config=( "dhcp" )
574 else
575 eerror "No DHCP client installed"
576 return 1
577 fi
578 # else
579 # config=( "null" )
580 # ewarn "Configuration not set for ${iface} - assuming null"
581 # fi
582 fi
583
584 einfo "Bringing up ${iface}"
585 eindent
586 for (( config_counter=0; config_counter<${#config[@]}; config_counter++ )); do
587 # Handle null and noop correctly
588 if [[ ${config[config_counter]} == "null" \
589 || ${config[config_counter]} == "noop" ]] ; then
590 eend 0
591 config_worked=true
592 continue
593 fi
594
595 # We convert it to an array - this has the added
596 # bonus of trimming spaces!
597 conf=( ${config[config_counter]} )
598 einfo "${conf[0]}"
599
600 # Do we have a function for our config?
601 if is_function "${conf[0]}_start" ; then
602 eindent
603 ${conf[0]}_start "${iface}" ; x=$?
604 eoutdent
605 [[ ${x} == 0 ]] && config_worked=true && continue
606 # We need to test to see if it's an IP address or a function
607 # We do this by testing if the 1st character is a digit
608 elif [[ ${conf[0]:0:1} == [[:digit:]] || ${conf[0]} == *:* ]] ; then
609 x="0"
610 if [[ ${RC_AUTO_INTERFACE} == "yes" ]] \
611 && is_function arping_address_exists ; then
612 if arping_address_exists "${iface}" "${conf[0]}" ; then
613 eerror "${conf[0]%%/*} already taken on ${iface}"
614 x="1"
615 fi
616 fi
617 [[ ${x} == "0" ]] && interface_add_address "${iface}" ${conf[@]}; x="$?"
618 eend "${x}" && config_worked=true && continue
619 else
620 if [[ ${conf[0]} == "dhcp" ]] ; then
621 eerror "No DHCP client installed"
622 else
623 eerror "No loaded modules provide \"${conf[0]}\" (${conf[0]}_start)"
624 fi
625 fi
626
627 if [[ -n ${fallback[config_counter]} ]] ; then
628 einfo "Trying fallback configuration"
629 config[config_counter]="${fallback[config_counter]}"
630 fallback[config_counter]=""
631
632 # Do we have a fallback route?
633 if [[ -n ${fallback_route[config_counter]} ]] ; then
634 x="fallback_route[config_counter]"
635 eval "routes_${ifvar}=( \"\${!x}\" )"
636 fallback_route[config_counter]=""
637 fi
638
639 (( config_counter-- )) # since the loop will increment it
640 continue
641 fi
642 done
643 eoutdent
644
645 # We return failure if no configuration parameters worked
646 ${config_worked} || return 1
647
648 # Start any modules with _post_start
649 for mod in ${MODULES[@]}; do
650 if is_function "${mod}_post_start" ; then
651 ${mod}_post_start "${iface}" || return 1
652 fi
653 done
654
655 return 0
656 }
657
658 # bool iface_stop(char *interface)
659 #
660 # iface_stop: bring down an interface. Don't trust information in
661 # /etc/conf.d/net since the configuration might have changed since
662 # iface_start ran. Instead query for current configuration and bring
663 # down the interface.
664 iface_stop() {
665 local iface="$1" i aliases need_begin=false mod
666 local RC_INDENTATION="${RC_INDENTATION}"
667
668 # pre Stop any modules
669 for mod in ${MODULES[@]}; do
670 is_function "${mod}_pre_stop" && ${mod}_pre_stop "${iface}"
671 done
672
673 einfo "Bringing down ${iface}"
674 eindent
675
676 # Collect list of aliases for this interface.
677 # List will be in reverse order.
678 if interface_exists "${iface}" ; then
679 aliases="$(interface_get_aliases_rev "${iface}")"
680 fi
681
682 # Stop aliases before primary interface.
683 # Note this must be done in reverse order, since ifconfig eth0:1
684 # will remove eth0:2, etc. It might be sufficient to simply remove
685 # the base interface but we're being safe here.
686 for i in ${aliases} ${iface}; do
687 # Stop all our modules
688 for mod in ${MODULES[@]}; do
689 is_function "${mod}_stop" && ${mod}_stop "${i}"
690 done
691
692 # A module may have removed the interface
693 if ! interface_exists "${iface}" ; then
694 eend 0
695 continue
696 fi
697
698 # Delete all the addresses for this alias
699 interface_del_addresses "${i}"
700
701 # Do final shut down of this alias
702 if [[ ${IN_BACKGROUND} != "true" \
703 && ${RC_DOWN_INTERFACE} == "yes" ]] ; then
704 ebegin "Shutting down ${i}"
705 interface_iface_stop "${i}"
706 eend "$?"
707 fi
708 done
709
710 # post Stop any modules
711 for mod in ${MODULES[@]}; do
712 # We have already taken down the interface, so no need to error
713 is_function "${mod}_post_stop" && ${mod}_post_stop "${iface}"
714 done
715
716 return 0
717 }
718
719 # bool run_start(char *iface)
720 #
721 # Brings up ${IFACE}. Calls preup, iface_start, then postup.
722 # Returns 0 (success) unless preup or iface_start returns 1 (failure).
723 # Ignores the return value from postup.
724 # We cannot check that the device exists ourselves as modules like
725 # tuntap make create it.
726 run_start() {
727 local iface="$1" IFVAR="$(bash_variable "$1")"
728
729 # We do this so users can specify additional addresses for lo if they
730 # need too - additional routes too
731 # However, no extra modules are loaded as they are just not needed
732 if [[ ${iface} == "lo" ]] ; then
733 metric_lo="0"
734 config_lo=( "127.0.0.1/8 brd 127.255.255.255" "${config_lo[@]}" )
735 routes_lo=( "127.0.0.0/8" "${routes_lo[@]}" )
736 fi
737
738 # We may not have a loaded module for ${iface}
739 # Some users may have "alias natsemi eth0" in /etc/modules.d/foo
740 # so we can work with this
741 # However, if they do the same with eth1 and try to start it
742 # but eth0 has not been loaded then the module gets loaded as
743 # eth0.
744 # Not much we can do about this :(
745 # Also, we cannot error here as some modules - such as bridge
746 # create interfaces
747 if ! interface_exists "${iface}" ; then
748 /sbin/modprobe "${iface}" &>/dev/null
749 fi
750
751 # Call user-defined preup function if it exists
752 if is_function preup ; then
753 einfo "Running preup function"
754 eindent
755 ( preup "${iface}" )
756 eend "$?" "preup ${iface} failed" || return 1
757 eoutdent
758 fi
759
760 # If config is set to noop and the interface is up with an address
761 # then we don't start it
762 local config
763 config="config_${IFVAR}[@]"
764 config=( "${!config}" )
765 if [[ ${config[0]} == "noop" ]] && interface_is_up "${iface}" true ; then
766 einfo "Keeping current configuration for ${iface}"
767 eend 0
768 else
769 # Remove noop from the config var
770 [[ ${config[0]} == "noop" ]] \
771 && eval "config_${IFVAR}=( "\"\$\{config\[@\]:1\}\"" )"
772
773 # There may be existing ip address info - so we strip it
774 if [[ ${RC_INTERFACE_KEEP_CONFIG} != "yes" \
775 && ${IN_BACKGROUND} != "true" ]] ; then
776 interface_del_addresses "${iface}"
777 fi
778
779 # Start the interface
780 if ! iface_start "${iface}" ; then
781 if [[ ${IN_BACKGROUND} != "true" ]] ; then
782 interface_exists "${iface}" && interface_down "${iface}"
783 fi
784 eend 1
785 return 1
786 fi
787 fi
788
789 # Call user-defined postup function if it exists
790 if is_function postup ; then
791 # We need to mark the service as started incase a
792 # postdown function wants to restart services that depend on us
793 mark_service_started "net.${iface}"
794 einfo "Running postup function"
795 eindent
796 ( postup "${iface}" )
797 eoutdent
798 fi
799
800 return 0
801 }
802
803 # bool run_stop(char *iface) {
804 #
805 # Brings down ${iface}. If predown call returns non-zero, then
806 # stop returns non-zero to indicate failure bringing down device.
807 # In all other cases stop returns 0 to indicate success.
808 run_stop() {
809 local iface="$1" IFVAR="$(bash_variable "$1")" x
810
811 # Load our ESSID variable so users can use it in predown() instead
812 # of having to write code.
813 local ESSID="$(get_options ESSID)" ESSIDVAR
814 [[ -n ${ESSID} ]] && ESSIDVAR="$(bash_variable "${ESSID}")"
815
816 # Call user-defined predown function if it exists
817 if is_function predown ; then
818 einfo "Running predown function"
819 eindent
820 ( predown "${iface}" )
821 eend $? "predown ${iface} failed" || return 1
822 eoutdent
823 elif is_net_fs /; then
824 eerror "root filesystem is network mounted -- can't stop ${iface}"
825 return 1
826 fi
827
828 iface_stop "${iface}" || return 1 # always succeeds, btw
829
830 # Mark us as inactive if called from the background
831 [[ ${IN_BACKGROUND} == "true" ]] && mark_service_inactive "net.${iface}"
832
833 # Call user-defined postdown function if it exists
834 if is_function postdown ; then
835 # We need to mark the service as stopped incase a
836 # postdown function wants to restart services that depend on us
837 [[ ${IN_BACKGROUND} != "true" ]] && mark_service_stopped "net.${iface}"
838 einfo "Running postdown function"
839 eindent
840 ( postdown "${iface}" )
841 eoutdent
842 fi
843
844 return 0
845 }
846
847 # bool run(char *iface, char *cmd)
848 #
849 # Main start/stop entry point
850 # We load modules here and remove any functions that they
851 # added as we may be called inside the same shell scope for another interface
852 run() {
853 local iface="$1" cmd="$2" r=1 RC_INDENTATION="${RC_INDENTATION}"
854 local starting=true
855 local -a MODULES mods
856 local IN_BACKGROUND="${IN_BACKGROUND}"
857
858 if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then
859 IN_BACKGROUND=true
860 else
861 IN_BACKGROUND=false
862 fi
863
864 # We need to override the exit function as runscript.sh now checks
865 # for it. We need it so we can mark the service as inactive ourselves.
866 unset -f exit
867
868 eindent
869 [[ ${cmd} == "stop" ]] && starting=false
870
871 # We force lo to only use these modules for a major speed boost
872 [[ ${iface} == "lo" ]] && modules_force=( "iproute2" "ifconfig" "system" )
873
874 if modules_load "${iface}" "${starting}" ; then
875 if [[ ${cmd} == "stop" ]] ; then
876 # Reverse the module list for stopping
877 mods=( "${MODULES[@]}" )
878 for ((i = 0; i < ${#mods[@]}; i++)); do
879 MODULES[i]=${mods[((${#mods[@]} - i - 1))]}
880 done
881
882 run_stop "${iface}" && r=0
883 remove_state "${iface}"
884 else
885 # Only hotplug on ethernet interfaces
886 if [[ ${IN_HOTPLUG} == 1 ]] ; then
887 if ! interface_is_ethernet "${iface}" ; then
888 eerror "We only hotplug for ethernet interfaces"
889 return 1
890 fi
891 fi
892
893 run_start "${iface}" && r=0
894 fi
895 fi
896
897 # Only apply best state if we're on auto
898 if [[ ${r} == "0" ]] ; then
899 local siface=""
900 if [[ ${RC_AUTO_INTERFACE} == "yes" ]] ; then
901 siface="$(select_best_interface)"
902 if [[ -n ${siface} ]] ; then
903 einfo "Selecting best interface: ${siface}"
904 fi
905 elif [[ ${cmd} == "start" ]] ; then
906 siface="${iface}"
907 fi
908 [[ -n ${siface} ]] && apply_state "${siface}"
909 else
910 if [[ ${cmd} == "start" ]] ; then
911 # Call user-defined failup if it exists
912 if is_function failup ; then
913 einfo "Running failup function"
914 eindent
915 ( failup "${iface}" )
916 eoutdent
917 fi
918 else
919 # Call user-defined faildown if it exists
920 if is_function faildown ; then
921 einfo "Running faildown function"
922 eindent
923 ( faildown "${iface}" )
924 eoutdent
925 fi
926 fi
927 [[ ${IN_BACKGROUND} == "true" ]] \
928 && mark_service_inactive "net.${iface}"
929 fi
930
931 return "${r}"
932 }
933
934 # void link_file(char *file)
935 #
936 # Move a config file from /etc to ${netdir} and creates a link if needed.
937 # This enables net-scripts to control the config file for interface management
938 # and allow /etc to become read only.
939 link_file() {
940 local file="$1"
941 local link="$(readlink "/etc/${file}" 2>/dev/null)"
942 if [[ ${link} != "${netdir}/${file}" ]] ; then
943 if [[ -f "/etc/${file}" ]] ; then
944 vewarn "Moving /etc/${file} to ${netdir}/${file} and creating link"
945 mv "/etc/${file}" "${netdir}"
946 ln -snf "${netdir}/${file}" "/etc/${file}"
947 fi
948 fi
949 }
950
951 # bool start(void)
952 #
953 # Start entry point so that we only have one function
954 # which localises variables and unsets functions
955 start() {
956 if [[ ${IN_HOTPLUG} == "1" ]] ; then
957 # If we've been called by hotplug, check if we have
958 # a policy for the interface for not starting
959 local x ifvar="$(bash_variable "${IFACE}")"
960 x="hotplug_${ifvar}"
961 if [[ ${!x} == "no" || ${!x} == "false" ]] ; then
962 eerror "Not starting interface ${IFACE} due to hotplug policy"
963 unset -f exit
964 mark_service_stopped "net.${IFACE}"
965 exit 1
966 fi
967 fi
968
969 if [[ ! -d "${statedir}/${IFACE}" ]] ; then
970 if ! mkdir -m 0755 -p "${statedir}/${IFACE}" ; then
971 eerror "Unable to create state directory!"
972 return 1
973 fi
974 fi
975
976 if [[ ${RC_AUTO_INTERFACE} == "yes" ]] ; then
977 link_file "resolv.conf"
978 link_file "ntp.conf"
979 link_file "yp.conf"
980 fi
981
982 einfo "Starting ${IFACE}"
983 run "${IFACE}" start
984 }
985
986 # bool stop(void)
987 #
988 # Stop entry point so that we only have one function
989 # which localises variables and unsets functions
990 stop() {
991 einfo "Stopping ${IFACE}"
992 run "${IFACE}" stop
993 }
994
995 # vim:ts=4

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.20