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