/[baselayout]/trunk/sh/net.sh
Gentoo

Contents of /trunk/sh/net.sh

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2547 - (hide annotations) (download) (as text)
Thu Apr 5 11:18:42 2007 UTC (10 years, 6 months ago) by uberlord
File MIME type: text/x-sh
File size: 12796 byte(s)
    Rewrite the core parts in C. We now provide librc so other programs can
    query runlevels, services and state without using bash. We also provide
    libeinfo so other programs can easily use our informational functions.

    As such, we have dropped the requirement of using bash as the init script
    shell. We now use /bin/sh and have strived to make the scripts as portable
    as possible. Shells that work are bash and dash. busybox works provided
    you disable s-s-d. If you have WIPE_TMP set to yes in conf.d/bootmisc you
    should disable find too.
    zsh and ksh do not work at this time.

    Networking support is currently being re-vamped also as it was heavily bash
    array based. As such, a new config format is available like so
    config_eth0="1.2.3.4/24 5.6.7.8/16"
    or like so
    config_eth0="'1.2.3.4 netmask 255.255.255.0' '5.6.7.8 netmask 255.255.0.0'"

    We will still support the old bash array format provided that /bin/sh IS
    a link it bash.

    ChangeLog for baselayout-1 can be found in our SVN repo.
1 uberlord 2547 #!/sbin/runscript
2     # Copyright 1999-2007 Gentoo Foundation
3     # Distributed under the terms of the GNU General Public License v2
4    
5     MODULESDIR="${RC_LIBDIR}/net"
6     MODULESLIST="${RC_SVCDIR}/nettree"
7     _config_vars="config"
8    
9     [ -z "${IN_BACKGROUND}" ] && IN_BACKGROUND=false
10    
11     depend() {
12     local IFACE=${SVCNAME#*.}
13     local IFVAR=$(echo -n "${IFACE}" | sed -e 's/[^[:alnum:]]/_/g')
14    
15     need localmount
16     after bootmisc
17     provide net
18     case "${IFACE}" in
19     lo|lo0) ;;
20     *)
21     after net.lo net.lo0
22     local prov=
23     eval prov=\$RC_NEED_${IFVAR}
24     [ -n "${prov}" ] && need ${prov}
25     eval prov=\$RC_USE_${IFVAR}
26     [ -n "${prov}" ] && use ${prov}
27     eval prov=\$RC_BEFORE_${IFVAR}
28     [ -n "${prov}" ] && before ${prov}
29     eval prov=\$RC_AFTER_${IFVAR}
30     [ -n "${prov}" ] && after ${prov}
31     eval prov=\$RC_PROVIDE_${IFVAR}
32     [ -n "${prov}" ] && provide ${prov}
33     ;;
34     esac
35     }
36    
37     _shell_var() {
38     echo -n "$1" | sed -e 's/[^[:alnum:]]/_/g'
39     }
40    
41     # Credit to David Leverton for this function which handily maps a bash array
42     # structure to positional parameters so existing configs work :)
43     # We'll deprecate arrays at some point though.
44     _get_array() {
45     if [ -n "${BASH}" ] ; then
46     case "$(declare -p "$1" 2>/dev/null)" in
47     "declare -a "*)
48     echo "set -- \"\${$1[@]}\""
49     return
50     ;;
51     esac
52     fi
53    
54     echo "eval set -- \"\$$1\""
55     }
56    
57     _wait_for_carrier() {
58     local timeout= efunc=einfon
59    
60     _has_carrier && return 0
61    
62     eval timeout=\$carrier_timeout_${IF_VAR}
63     timeout=${timeout:-5}
64    
65     [ -n "${RC_EBUFFER}" ] && efunc=einfo
66     ${efunc} "Waiting for carrier (${timeout} seconds) "
67     while [ ${timeout} -gt 0 ] ; do
68     sleep 1
69     if _has_carrier ; then
70     [ -z "${RC_EBUFFER}" ] && echo
71     return 0
72     fi
73     timeout=$((${timeout} - 1))
74     [ -z "${RC_EBUFFER}" ] && echo -n "."
75     done
76    
77     echo
78     return 1
79     }
80    
81     _netmask2cidr() {
82     local i= len=0
83    
84     local IFS=.
85     for i in $1; do
86     while [ ${i} != "0" ] ; do
87     len=$((${len} + 1))
88     i=$((${i} >> 1))
89     done
90     done
91    
92     echo "${len}"
93     }
94    
95     _configure_variables() {
96     local var= v= t=
97    
98     for var in ${_config_vars} ; do
99     local v=
100     for t in "$@" ; do
101     eval v=\$${var}_${t}
102     if [ -n "${v}" ] ; then
103     eval ${var}_${IFVAR}=\$${var}_${t}
104     continue 2
105     fi
106     done
107     done
108     }
109    
110     _show_address() {
111     einfo "received address $(_get_inet_address "${IFACE}")"
112     }
113    
114     # Basically sorts our modules into order and saves the list
115     _gen_module_list() {
116     local x= f=
117     if [ -s "${MODULESLIST}" -a "${MODULESLIST}" -nt "${MODULESDIR}" ] ; then
118     local update=false
119     for x in "${MODULESDIR}"/* ; do
120     [ -e "${x}" ] || continue
121     if [ "${x}" -nt "${MODULESLIST}" ] ; then
122     update=true
123     break
124     fi
125     done
126     ${update} || return 0
127     fi
128    
129     einfo "Caching network module dependencies"
130     # Run in a subshell to protect the main script
131     (
132     after() {
133     eval ${MODULE}_after="\"\${${MODULE}_after}\${${MODULE}_after:+ }$*\""
134     }
135    
136     before() {
137     local mod=${MODULE}
138     local MODULE=
139     for MODULE in "$@" ; do
140     after "${mod}"
141     done
142     }
143    
144     program() {
145     if [ "$1" = "start" -o "$1" = "stop" ] ; then
146     local s="$1"
147     shift
148     eval ${MODULE}_program_${s}="\"\${${MODULE}_program_${s}}\${${MODULE}_program_${s}:+ }$*\""
149     else
150     eval ${MODULE}_program="\"\${${MODULE}_program}\${${MODULE}_program:+ }$*\""
151     fi
152     }
153    
154     provide() {
155     eval ${MODULE}_provide="\"\${${MODULE}_provide}\${${MODULE}_provide:+ }$*\""
156     local x
157     for x in $* ; do
158     eval ${x}_providedby="\"\${${MODULE}_providedby}\${${MODULE}_providedby:+ }${MODULE}\""
159     done
160     }
161    
162     for MODULE in "${MODULESDIR}"/* ; do
163     sh -n "${MODULE}" || continue
164     . "${MODULE}" || continue
165     MODULE=${MODULE#${MODULESDIR}/}
166     MODULE=${MODULE%.sh}
167     eval ${MODULE}_depend
168     MODULES="${MODULES} ${MODULE}"
169     done
170    
171     VISITED=
172     SORTED=
173     visit() {
174     case " ${VISITED} " in
175     *" $1 "*) return ;;
176     esac
177     VISITED="${VISITED} $1"
178    
179     eval AFTER=\$${1}_after
180     for MODULE in ${AFTER} ; do
181     eval PROVIDEDBY=\$${MODULE}_providedby
182     if [ -n "${PROVIDEDBY}" ] ; then
183     for MODULE in ${PROVIDEDBY} ; do
184     visit "${MODULE}"
185     done
186     else
187     visit "${MODULE}"
188     fi
189     done
190    
191     eval PROVIDE=\$${1}_provide
192     for MODULE in ${PROVIDE} ; do
193     visit "${MODULE}"
194     done
195    
196     eval PROVIDEDBY=\$${1}_providedby
197     [ -z "${PROVIDEDBY}" ] && SORTED="${SORTED} $1"
198     }
199    
200     for MODULE in ${MODULES} ; do
201     visit "${MODULE}"
202     done
203    
204     > "${MODULESLIST}"
205     i=0
206     for MODULE in ${SORTED} ; do
207     eval PROGRAM=\$${MODULE}_program
208     eval PROGRAM_START=\$${MODULE}_program_start
209     eval PROGRAM_STOP=\$${MODULE}_program_stop
210     #for x in ${PROGRAM} ; do
211     # [ -x "${x}" ] || continue 2
212     #done
213     eval PROVIDE=\$${MODULE}_provide
214     echo "module_${i}='${MODULE}'" >> "${MODULESLIST}"
215     echo "module_${i}_program='${PROGRAM}'" >> "${MODULESLIST}"
216     echo "module_${i}_program_start='${PROGRAM_START}'" >> "${MODULESLIST}"
217     echo "module_${i}_program_stop='${PROGRAM_STOP}'" >> "${MODULESLIST}"
218     echo "module_${i}_provide='${PROVIDE}'" >> "${MODULESLIST}"
219     i=$((${i} + 1))
220     done
221     echo "module_${i}=" >> "${MODULESLIST}"
222     )
223    
224     return 0
225     }
226    
227     _load_modules() {
228     # Ensure our list is up to date
229     _gen_module_list
230    
231     local starting=$1 mymods=
232    
233     MODULES=
234     if [ "${IFACE}" != "lo" -a "${IFACE}" != "lo0" ] ; then
235     eval mymods=\$modules_${IFVAR}
236     [ -z "${mymods}" ] && mymods=${modules}
237     fi
238    
239     . "${MODULESLIST}"
240     local i=-1 x= mod= f= provides=
241     while true ; do
242     i=$((${i} + 1))
243     eval mod=\$module_${i}
244     [ -z "${mod}" ] && break
245     [ -e "${MODULESDIR}/${mod}.sh" ] || continue
246    
247     eval set -- \$module_${i}_program
248     if [ -n "$1" ] ; then
249     x=
250     for x in "$@" ; do
251     [ -x "${x}" ] && break
252     done
253     [ -x "${x}" ] || continue
254     fi
255     if ${starting} ; then
256     eval set -- \$module_${i}_program_start
257     else
258     eval set -- \$module_${i}_program_stop
259     fi
260     if [ -n "$1" ] ; then
261     x=
262     for x in "$@" ; do
263     [ -x "${x}" ] && break
264     done
265     [ -x "${x}" ] || continue
266     fi
267    
268     eval provides=\$module_${i}_provide
269     if ${starting} ; then
270     case " ${mymods} " in
271     *" !${mod} "*) continue ;;
272     *" !${provides} "*) [ -n "${provides}" ] && continue ;;
273     esac
274     fi
275     MODULES="${MODULES}${MODULES:+ }${mod}"
276    
277     # Now load and wrap our functions
278     if ! . "${MODULESDIR}/${mod}.sh" ; then
279     eend 1 "${SVCNAME}: error loading module \`${mod}'"
280     exit 1
281     fi
282    
283     [ -z "${provides}" ] && continue
284    
285     # Wrap our provides
286     local f=
287     for f in pre_start start post_start ; do
288     eval "${provides}_${f}() { type ${mod}_${f} >/dev/null 2>/dev/null || return 0; ${mod}_${f} \"\$@\"; }"
289     done
290    
291     eval module_${mod}_provides="${provides}"
292     eval module_${provides}_providedby="${mod}"
293     done
294    
295     # Wrap our preferred modules
296     for mod in ${mymods} ; do
297     case " ${MODULES} " in
298     *" ${mod} "*)
299     eval x=\$module_${mod}_provides
300     [ -z "${x}" ] && continue
301     for f in pre_start start post_start ; do
302     eval "${x}_${f}() { type ${mod}_${f} >/dev/null 2>/dev/null || return 0; ${mod}_${f} \"\$@\"; }"
303     done
304     eval module_${x}_providedby="${mod}"
305     ;;
306     esac
307     done
308    
309     # Finally remove any duplicated provides from our list if we're starting
310     # Otherwise reverse the list
311     local LIST="${MODULES}" p=
312     MODULES=
313     if ${starting} ; then
314     for mod in ${LIST} ; do
315     eval x=\$module_${mod}_provides
316     if [ -n "${x}" ] ; then
317     eval p=\$module_${x}_providedby
318     [ "${mod}" != "${p}" ] && continue
319     fi
320     MODULES="${MODULES}${MODULES:+ }${mod}"
321     done
322     else
323     for mod in ${LIST} ; do
324     MODULES="${mod}${MODULES:+ }${MODULES}"
325     done
326     fi
327    
328     veinfo "Loaded modules: ${MODULES}"
329     }
330    
331     _load_config() {
332     eval "$(_get_array "config_${IFVAR}")"
333     if [ "${IFACE}" = "lo" -o "${IFACE}" = "lo0" ] ; then
334     set -- "127.0.0.1/8" "$@"
335     else
336     if [ $# -eq 0 ] ; then
337     ewarn "No configuration specified; defaulting to DHCP"
338     set -- "dhcp"
339     fi
340     fi
341    
342     # We store our config in an array like vars
343     # so modules can influence it
344     config_index=0
345     for cmd in "$@" ; do
346     eval config_${config_index}="'${cmd}'"
347     config_index=$((${config_index} + 1))
348     done
349     # Terminate the list
350     eval config_${config_index}=
351    
352     config_index=0
353     eval $(_get_array fallback_${IFVAR})
354     for cmd in "$@" ; do
355     eval fallback_${config_index}="'${cmd}'"
356     config_index=$((${config_index} + 1))
357     done
358     # Terminate the list
359     eval fallback_${config_index}=
360    
361     # Don't set to zero, so any net modules don't have to do anything extra
362     config_index=-1
363     }
364    
365     start() {
366     local IFACE=${SVCNAME#*.} oneworked=false module=
367     local IFVAR=$(_shell_var "${IFACE}") cmd= metric=0 our_metric=$metric
368    
369     einfo "Bringing up interface ${IFACE}"
370     eindent
371    
372     if [ -z "${MODULES}" ] ; then
373     local MODULES=
374     _load_modules true
375     fi
376    
377     _up 2>/dev/null
378    
379     if type preup >/dev/null 2>/dev/null ; then
380     ebegin "Running preup"
381     eindent
382     preup || return 1
383     eoutdent
384     fi
385    
386     for module in ${MODULES} ; do
387     if type "${module}_pre_start" >/dev/null 2>/dev/null ; then
388     if ! ${module}_pre_start ; then
389     eend 1
390     exit 1
391     fi
392     fi
393     done
394    
395     local config= config_index=
396     _load_config
397     config_index=0
398    
399     if [ -n "${our_metric}" ] ; then
400     metric=${our_metric}
401     elif [ "${IFACE}" != "lo" -a "${IFACE}" != "lo0" ] ; then
402     metric=$((${metric} + $(_ifindex)))
403     fi
404    
405     while true ; do
406     eval config=\$config_${config_index}
407     [ -z "${config}" ] && break
408    
409     set -- "${config}"
410     ebegin "$1"
411     eindent
412     case "$1" in
413     noop)
414     if [ -n "$(_get_inet_address)" ] ; then
415     oneworked=true
416     break
417     fi
418     ;;
419     null) : ;;
420     [0-9]*|*:*) _add_address ${config} ;;
421     *)
422     if type "${config}_start" >/dev/null 2>/dev/null ; then
423     "${config}"_start
424     else
425     eerror "nothing provides \`${config}'"
426     fi
427     ;;
428     esac
429     if eend $? ; then
430     oneworked=true
431     else
432     eval config=\$fallback_${IFVAR}
433     if [ -n "${config}" ] ; then
434     einfo "Trying fallback configuration"
435     eval config_${config_index}=\$fallback_${IFVAR}
436     eval fallback_${config_index}=
437     config_index=$((${config_index} - 1))
438     fi
439     fi
440     eoutdent
441     config_index=$((${config_index} + 1))
442     done
443    
444     if ! ${oneworked} ; then
445     if type failup >/dev/null 2>/dev/null ; then
446     ebegin "Running failup"
447     eindent
448     failup
449     eoutdent
450     fi
451     return 1
452     fi
453    
454     local hidefirstroute=false first=true routes=
455     eval "$(_get_array "routes_${IFVAR}")"
456     if [ "${IFACE}" = "lo" -o "${IFACE}" = "lo0" ] ; then
457     set -- "127.0.0.0/8 via 127.0.0.1" "$@"
458     hidefirstroute=true
459     fi
460     for cmd in "$@" ; do
461     if ${first} ; then
462     first=false
463     einfo "Adding routes"
464     fi
465     eindent
466     ebegin "${cmd}"
467     # Work out if we're a host or a net if not told
468     case "${cmd}" in
469     *" -net "*|*" -host "*) ;;
470     *" netmask "*) cmd="-net ${cmd}" ;;
471     *)
472     case "${cmd%% *}" in
473     *.*.*.*/32) cmd="-host ${cmd}" ;;
474     *.*.*.*/*|0.0.0.0|default) cmd="-net ${cmd}" ;;
475     *) cmd="-host ${cmd}" ;;
476     esac
477     ;;
478     esac
479     if ${hidefirstroute} ; then
480     _add_route ${cmd} >/dev/null 2>/dev/null
481     hidefirstroute=false
482     else
483     _add_route ${cmd} >/dev/null
484     fi
485     eend $?
486     eoutdent
487     done
488    
489     for module in ${MODULES} ; do
490     if type "${module}_post_start" >/dev/null 2>/dev/null ; then
491     if ! ${module}_post_start ; then
492     eend 1
493     exit 1
494     fi
495     fi
496     done
497    
498     if type postup >/dev/null 2>/dev/null ; then
499     ebegin "Running postup"
500     eindent
501     postup
502     eoutdent
503     fi
504    
505     return 0
506     }
507    
508     stop() {
509     local IFACE=${SVCNAME#*.} module=
510     local IFVAR=$(_shell_var "${IFACE}") opts=
511    
512     einfo "Bringing down interface ${IFACE}"
513     eindent
514    
515     if [ -z "${MODULES}" ] ; then
516     local MODULES=
517     _load_modules false
518     fi
519    
520     if type predown >/dev/null 2>/dev/null ; then
521     ebegin "Running predown"
522     eindent
523     predown || return 1
524     eoutdent
525     fi
526    
527     for module in ${MODULES} ; do
528     if type "${module}_pre_stop" >/dev/null 2>/dev/null ; then
529     if ! ${module}_pre_stop ; then
530     eend 1
531     exit 1
532     fi
533     fi
534     done
535    
536     for module in ${MODULES} ; do
537     if type "${module}_stop" >/dev/null 2>/dev/null ; then
538     ${module}_stop
539     fi
540     done
541    
542     _delete_addresses "${IFACE}"
543    
544     for module in ${MODULES} ; do
545     if type "${module}_post_stop" >/dev/null 2>/dev/null ; then
546     ${module}_post_stop
547     fi
548     done
549    
550     [ "${IN_BACKGROUND}" != "true" ] && \
551     [ "${IFACE}" != "lo" -a "${IFACE}" != "lo0" ] && \
552     _down 2>/dev/null
553    
554     [ -x /sbin/resolvconf ] && resolvconf -d "${IFACE}"
555    
556     if type predown >/dev/null 2>/dev/null ; then
557     ebegin "Running postdown"
558     eindent
559     postdown
560     eoutdent
561     fi
562    
563     return 0
564     }
565    
566     # vim: set ts=4 :

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.20