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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 872 - (show annotations) (download)
Thu Jan 27 12:37:06 2005 UTC (14 years, 3 months ago) by uberlord
File size: 23313 byte(s)
removed udhcpc-* and dhclient-* helper modules and replaced them with a
generic dhcp module which caters for all interfaces and dhcp clients that
need it.
We now prefer iproute2 over ifconfig if both are installed.

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

Properties

Name Value
svn:eol-style native
svn:executable *
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.20