/[vps]/baselayout-vserver/trunk/lib/rcscripts/net.modules.d/helpers.d/functions
Gentoo

Contents of /baselayout-vserver/trunk/lib/rcscripts/net.modules.d/helpers.d/functions

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (show annotations) (download)
Sat Sep 3 16:10:27 2005 UTC (8 years, 10 months ago) by hollow
File size: 12753 byte(s)
import initial baselayout sources (1.12.0_pre8)
1 #!/bin/bash
2 # Copyright (c) 2004-2005 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4
5 # We will be loaded after conf.d/rc and conf.d/net so we can set a default
6 # here.
7 RC_AUTO_INTERFACE="${RC_AUTO_INTERFACE:-no}"
8
9 netdir="/var/lib/net-scripts"
10 statedir="${netdir}/state"
11
12 # Contributed by Roy Marples (uberlord@gentoo.org)
13
14 # char* interface_device(char *iface)
15 #
16 # Gets the base device of the interface
17 # Can handle eth0:1 and eth0.1
18 # Which returns eth0 in this case
19 interface_device() {
20 local dev="${1%%.*}"
21 [[ ${dev} == "$1" ]] && dev="${1%%:*}"
22 echo "${dev}"
23 }
24
25 # char* interface_type(char* iface)
26 #
27 # Returns the base type of the interface
28 # eth, ippp, etc
29 interface_type() {
30 echo "${1%%[0-9]*}"
31 }
32
33 # void save_state(char *interface)
34 #
35 # Saves state information regarding the interface
36 save_state() {
37 local iface="$1"
38 local d="${statedir}/${iface}"
39
40 [[ ! -d ${d} ]] && mkdir -m 0755 -p "${d}"
41 cp -a /etc/resolv.conf /etc/ntp.conf /etc/yp.conf "${d}" 2>/dev/null
42 }
43
44 # void remove_state(char *interface)
45 #
46 # Removes state information regarding the interface
47 remove_state() {
48 local d="${statedir}/$1"
49
50 [[ -d ${d} ]] && rm -Rf "${d}"
51 [[ ! ${2:-true} ]] && mkdir -m 0755 -p "${d}"
52 }
53
54 # void apply_state(char *interface)
55 #
56 # Apply's state information about the interface to the system
57 # If the files in the state dir are not links back to etc then
58 # we create them if RC_AUTO_INTERFACE="yes"
59 #
60 apply_state() {
61 local iface="$1"
62
63 if [[ -z ${iface} ]]; then
64 iface=$( select_best_interface )
65 [[ -z ${iface} ]] && return
66 fi
67
68 local d="${statedir}/${iface}"
69 if [[ -d ${d} ]]; then
70 local files=$( ls "${d}" )
71 if [[ -n ${files} ]] ; then
72 if [[ ${RC_AUTO_INTERFACE} == "yes" ]]; then
73 cp -aR "${d}"/* "${netdir}"
74 local file
75 for file in ${files} ; do
76 # Skip .sv files
77 [[ ${file} == *".sv" ]] && contine
78 local link=$( readlink "/etc/${file}" 2>/dev/null )
79 if [[ ${link} != "${netdir}/${file}" ]]; then
80 [[ -e "/etc/${file}" ]] && rm -f "/etc/${file}"
81 ln -snf "${netdir}/${file}" "/etc/${file}"
82 fi
83 done
84 else
85 cp -ar "${d}"/* /etc
86 fi
87 fi
88 fi
89
90 [[ ${RC_AUTO_INTERFACE} == "yes" ]] && merge_configs
91 }
92
93 # char* order_interfaces(bool require_gateway)
94 #
95 # Lists the interfaces in route metric order that we have configured
96 # (ie a state dir exists)
97 # require_gateway defaults to false
98 order_interfaces() {
99 local ifaces
100 if [[ ${1:-false} == "true" ]]; then
101 ifaces=$(awk '$2!="Gateway" { print $7, $1 }' /proc/net/route \
102 | sort -n | cut -d' ' -f2 | uniq)
103 else
104 ifaces=$(awk '$2=="00000000" { print $7, $1 }' /proc/net/route \
105 | sort -n | cut -d' ' -f2 )
106 fi
107 local i order
108 for i in ${ifaces}; do
109 [[ -d "${statedir}/${i}" ]] && order="${order}${i} "
110 done
111
112 echo "${order}"
113 }
114
115 # void merge_resolv()
116 #
117 # Merges the resolv.conf info from active interfaces
118 merge_resolv() {
119 local -a ifaces=( $(order_interfaces) )
120 local i j f
121
122 # We only work for ifaces with a resolv.conf
123 j=${#ifaces[@]}
124 for (( i=0; i<j; i++ )); do
125 [[ ! -e "${statedir}/${ifaces[i]}/resolv.conf" ]] && unset ifaces[i]
126 done
127 ifaces=( "${ifaces[@]}" )
128
129 # No point merging unless there are two or more interfaces
130 [[ ${#ifaces[@]} -lt 2 ]] && return
131
132 veinfo "Merging resolv.conf from interfaces ${ifaces[@]}"
133
134 local -a search srvs
135 j=0
136 for (( i=0; i<${#ifaces[@]}; i++ )); do
137 f="${statedir}/${ifaces[i]}/resolv.conf"
138 srvs[i]=$( sed -n -e 's/^[ \t]*nameserver[ \t]*\([^#]\)/\1/p' "${f}" \
139 | sed 2q )
140 if [[ -z ${srvs[i]} ]]; then
141 unset srvs[i]
142 continue
143 fi
144
145 search[i]=$( sed -n -e 's/^[ \t]*\(domain\|search\)[ \t]*\([^#]\)/\2/p' \
146 "${f}" | sed -e '$!d' )
147
148 # No point in handling more than 3 interfaces due to libc limits
149 (( j++ ))
150 [[ ${j} -gt 2 ]] && break
151 done
152 srvs=( "${srvs[@]}" )
153 search=( ${search[@]} )
154
155 local new_srvs
156 j=0
157 # Add interface primary nameservers
158 for (( i=0;i<${#srvs[@]}; i++ )); do
159 local -a n=( ${srvs[i]} )
160 if [[ " ${new_srvs} " != *" ${n[0]} "* ]]; then
161 new_srvs="${new_srvs} ${n[0]}"
162 # libc can only handle 3 name servers
163 (( j++ ))
164 [[ ${j} -gt 2 ]] && break
165 fi
166 done
167
168 # Add interface secondary nameservers
169 if [[ ${j} -lt 3 ]]; then
170 for (( i=0;i<${#srvs[@]}; i++ )); do
171 local -a n=( ${srvs[i]} )
172 [[ -z ${n[1]} ]] && continue
173 if [[ " ${new_srvs} " != *" ${n[1]} "* ]]; then
174 new_srvs="${new_srvs} ${n[1]}"
175 # libc can only handle 3 name servers
176 (( j++ ))
177 [[ ${j} -gt 2 ]] && break
178 fi
179 done
180 fi
181
182 local new_search n_search=0
183 for i in ${search[@]}; do
184 if [[ " ${new_search} " != *" ${i} "* ]]; then
185 new_search="${new_search} ${i}"
186 # lib limits us to 6 search domains
187 (( n_search++ ))
188 [[ ${n_search} -gt 5 ]] && break
189 fi
190 done
191
192 # Now we create a new resolv.conf to use
193 local f="${netdir}/resolv.conf.$$"
194 echo "# Generated by net-scripts from interfaces ${ifaces[@]}" > "${f}"
195 chmod 644 "${f}"
196 for i in ${new_srvs[@]}; do
197 echo "nameserver ${i}" >> "${f}"
198 done
199 if [[ -n ${new_search} ]]; then
200 if [[ ${n_search} == "1" ]]; then
201 echo "domain${new_search}" >> "${f}"
202 else
203 echo "search${new_search}" >> "${f}"
204 fi
205 fi
206 mv "${f}" "${netdir}/resolv.conf"
207 }
208
209
210 # void merge_ntp()
211 #
212 # Merges the ntp.conf info from active interfaces
213 merge_ntp() {
214 local -a ifaces=( $(order_interfaces) )
215 local i j f
216
217 # We only work for ifaces with a ntp.conf
218 j=${#ifaces[@]}
219 for (( i=0; i<j; i++ )); do
220 [[ ! -e "${statedir}/${ifaces[i]}/ntp.conf" ]] && unset ifaces[i]
221 done
222 ifaces=( "${ifaces[@]}" )
223
224 # No point merging unless there are two or more interfaces
225 [[ ${#ifaces[@]} -lt 2 ]] && return
226
227 veinfo "Merging ntp.conf from interfaces ${ifaces[@]}"
228
229 local srvs
230 for (( i=0; i<${#ifaces[@]}; i++ )); do
231 f="${statedir}/${ifaces[i]}/ntp.conf"
232 srvs="${srvs} $( sed -n -e 's/^[ \t]*server[ \t]*\([^#]\)/\1/p' "${f}" )"
233 done
234
235 # ntp does it's own preference list, so we just remove duplicates
236 sort_unique() {
237 set -- " ${@/%/\n}"
238 echo -e "$@" | sort -u
239 }
240
241 srvs=$( sort_unique ${srvs} )
242
243 f="${netdir}/ntp.conf.$$"
244 echo "# Generated by net-scripts for interfaces ${ifaces[@]}" > "${f}"
245 chmod 644 "${f}"
246
247 echo "restrict default noquery notrust nomodify" >> "${f}"
248 echo "restrict 127.0.0.1" >> "${f}"
249
250 for i in ${srvs}; do
251 echo "restrict ${i} nomodify notrap noquery" >> "${f}"
252 echo "server ${i}" >> "${f}"
253 done
254
255 echo "driftfile /var/lib/ntp/ntp.drift" >> "${f}"
256 echo "logfile /var/log/ntp.log" >> "${f}"
257
258 mv "${f}" "${netdir}/ntp.conf"
259 }
260
261 # void merge_configs()
262 #
263 # Merge config files together
264 merge_configs() {
265 merge_resolv
266 merge_ntp
267 }
268
269 # char* select_best_interface()
270 #
271 # Selects the best interface to apply state information to
272 # This is currently based on routing metrics
273 select_best_interface() {
274 local -a ifs=( $(order_interfaces true) )
275
276 # We never select lo as the best interface
277 local x=" ${ifs[@]} "
278 ifs=( ${x// lo / } )
279
280 local iface
281 for iface in ${ifs[@]} ; do
282 if [[ -e "${statedir}/${iface}/resolv.conf" ]]; then
283 echo "${iface}"
284 return 0
285 fi
286 done
287
288 echo "${ifs[0]}"
289 }
290
291 # int calculate_metric(char *interface)
292 #
293 # Calculates the best metric for the interface
294 # The Linux kernel does not use this at the moment, but we use it so that
295 # default routes remain and we can work out the "best" interface
296 calculate_metric() {
297 local iface="$1" exclude='$1!="Iface" && $1!="lo"'
298
299 # Have we already got a metric?
300 local m=$( awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \
301 /proc/net/route )
302 if [[ -n ${m} ]]; then
303 echo "${m}"
304 return 0
305 fi
306
307 local itype=$( interface_type "${iface}" ) x i
308
309 # If we're not a wireless device then exclude wireless from the
310 # routing table so we stay < 1000
311 if [[ -e /proc/net/wireless ]]; then
312 if ! grep -q "^[ \t]*${iface}:[ \t]" /proc/net/wireless ; then
313 local i=$( sed -n -e 's/^[ \t]*\(.*\):.*/\1/p' /proc/net/wireless )
314 for x in ${i} ; do
315 exclude="${exclude} && "'$1'"!=\"${x}\""
316 done
317 fi
318 fi
319
320 # Exclude ppp and ippp as well
321 local ix="ppp|ippp"
322 [[ ${itype} == "ppp" ]] && ix="ippp"
323 [[ ${itype} == "ippp" ]] && ix="ppp"
324 i=$( sed -n -e 's/^[ ]*\('${ix}'[0-9]*\):.*$/\1/p' /proc/net/dev )
325 for x in ${i} ; do
326 exclude="${exclude} && "'$1'"!=\"${x}\""
327 done
328
329 local m=$( awk "${exclude} { print "'$7'" }" /proc/net/route \
330 | sort -rn | head -n 1 | cut -d' ' -f2 )
331 m="${m:--1}"
332 (( m ++ ))
333
334 # If we're a wireless device then add 1000 so that wired interfaces take preference
335 if [[ -e /proc/net/wireless ]]; then
336 grep -q "^[ \t]*${iface}:[ \t]" /proc/net/wireless && (( m+= 1000 ))
337 fi
338
339 # If we're a ppp device then we add 2000 for ISDN, otherwise 3000
340 [[ ${itype} == "ippp" ]] && (( m+= 2000 ))
341 [[ ${itype} == "ppp" ]] && (( m+= 3000 ))
342
343 echo "${m}"
344 }
345
346 # int netmask2cidr(char *netmask)
347 #
348 # Returns the CIDR of a given netmask
349 netmask2cidr() {
350 local binary="" i bin
351
352 for i in ${1//./ }; do
353 bin=""
354 while [[ ${i} != "0" ]]; do
355 bin=$[${i}%2]${bin}
356 (( i=i>>1 ))
357 done
358 binary="${binary}${bin}"
359 done
360 binary="${binary%%0*}"
361 echo "${#binary}"
362 }
363
364 # char* netmask2cidr(int cidr)
365 #
366 # Returns the netmask of a given CIDR
367 cidr2netmask() {
368 local cidr="$1" netmask="" done=0 i sum=0 cur=128
369 local octets frac
370
371 (( octets=cidr/8 ))
372 (( frac=cidr%8 ))
373 while [[ octets -gt 0 ]]; do
374 netmask="${netmask}.255"
375 (( octets-- ))
376 (( done++ ))
377 done
378
379 if [[ ${done} -lt 4 ]]; then
380 for (( i=0; i<${frac}; i++ )); do
381 (( sum+=cur ))
382 (( cur/=2 ))
383 done
384 netmask="${netmask}.${sum}"
385 (( done++ ))
386
387 while [[ ${done} -lt 4 ]]; do
388 netmask="${netmask}.0"
389 (( done++ ))
390 done
391 fi
392
393 echo "${netmask:1}"
394 }
395
396 # char* ip_network(char *ip, char *netmask)
397 #
398 # Returns the network of the ip address
399 # ip can be 192.168.0.51/24
400 # or
401 # ip can be 192.168.0.51 and netmask is 255.255.255.0
402 ip_network() {
403 local ip="$1" mask="$2" i network x
404
405 # If we didn't get parameter 2 then assume we have a CIDR
406 if [[ -z ${mask} ]]; then
407 mask="${ip##*/}"
408 [[ -z ${mask} || ${mask} == ${ip} ]] && return 1
409 mask=$( cidr2netmask "${mask}" )
410 ip="${ip%%/*}"
411 fi
412
413 ip=( ${ip//./ } )
414 mask=( ${mask//./ } )
415
416 for (( i=0; i<4; i++ )); do
417 (( x=ip[i] & mask[i] ))
418 network="${network}${x}"
419 [[ ${i} -lt 3 ]] && network="${network}."
420 done
421
422 echo "${network}"
423 }
424
425 # bool clean_pidfile(char *file)
426 #
427 # Removes the given pidfile if the process is not running
428 # Returns 1 if the process is still running otherwise 0
429 clean_pidfile() {
430 local pidfile="$1"
431
432 [[ ! -f ${pidfile} ]] && return 0
433 local pid=$( < "${pidfile}" )
434
435 if [[ -n ${pid} ]]; then
436 local cmd="${pidfile##*/}"
437 cmd="${cmd%%-*}"
438 ps -p "${pid}" 2>/dev/null | grep -q "${cmd}" && return 1
439 fi
440
441 rm -f "${pidfile}"
442 return 0
443 }
444
445 # bool process_finished(int pid, char* cmd)
446 #
447 # We wait for 10 seconds until the command ${cmd}
448 # stops running on the process ${pid}
449 process_finished() {
450 local i pid="$1" cmd="$2" secs="${3:-9}"
451
452 for (( i=0; i<secs; i++ )); do
453 ps -p "${pid}" 2>/dev/null | grep -q "${cmd}" || return 0
454 sleep 1
455 done
456
457 return 1
458 }
459
460 # void function_wrap(char* source, char* target)
461 #
462 # wraps function calls - for example function_wrap(this, that)
463 # maps function names this_* to that_*
464 function_wrap() {
465 local i
466
467 [[ $( type -t "${2}_provides" ) == "function" ]] && return
468
469 for i in $( typeset -f | grep -o '^'"${1}"'_[^ ]*' ); do
470 eval "${2}${i#${1}}() { ${i} \"\$@\"; }"
471 done
472 }
473
474 # char[] * expand_parameters(char *cmd)
475 #
476 # Returns an array after expanding parameters. For example
477 # "192.168.{1..3}.{1..3}/24 brd +"
478 # will return
479 # "192.168.1.1/24 brd +"
480 # "192.168.1.2/24 brd +"
481 # "192.168.1.3/24 brd +"
482 # "192.168.2.1/24 brd +"
483 # "192.168.2.2/24 brd +"
484 # "192.168.2.3/24 brd +"
485 # "192.168.3.1/24 brd +"
486 # "192.168.3.2/24 brd +"
487 # "192.168.3.3/24 brd +"
488 expand_parameters() {
489 local x="$( eval echo ${@// /_} )"
490 local -a a=( ${x} )
491
492 a=( "${a[@]/#/\"}" )
493 a=( "${a[@]/%/\"}" )
494 echo "${a[*]//_/ }"
495 }
496
497 # void configure_variables(char *interface, char *option1, [char *option2])
498 #
499 # Maps configuration options from <variable>_<option> to <variable>_<iface>
500 # option2 takes precedence over option1
501 configure_variables() {
502 local iface="$1" option1="$2" option2="$3"
503
504 local mod func x i
505 local -a ivars ovars1 ovars2
506 local ifvar=$( bash_variable "${iface}" )
507
508 for mod in ${MODULES[@]}; do
509 func="${mod}_get_vars"
510 if [[ $( type -t ${func} ) == "function" ]]; then
511 ivars=( $( "${func}" "${ifvar}" ) )
512 ovars1=( $( "${func}" "${option1}" ) )
513 [[ -n ${option2} ]] && ovars2=( $( "${func}" "${option2}" ) )
514 for ((i = 0; i<${#ivars[@]}; i++)); do
515 x=""
516 [[ -n ${ovars2[i]} ]] && eval x=( \"\$\{${ovars2[i]}\[@\]\}\" )
517 [[ -z ${x} ]] && eval x=( \"\$\{${ovars1[i]}\[@\]\}\" )
518 [[ -n ${x} ]] && eval "${ivars[i]}=( "\"\$\{x\[@\]\}\"" )"
519 done
520 fi
521 done
522
523 return 0
524 }
525
526 # vim:ts=4

  ViewVC Help
Powered by ViewVC 1.1.20