Magellan Linux

Contents of /mcore-src/trunk/mcore-tools/dracut/net-lib.sh

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2094 - (show annotations) (download) (as text)
Fri Sep 27 07:47:47 2013 UTC (10 years, 7 months ago) by niro
File MIME type: application/x-sh
File size: 13775 byte(s)
-start mcored only if an active iface was found and use net-lib to find this iface
1 #!/bin/sh
2 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
3 # ex: ts=8 sw=4 sts=4 et filetype=sh
4
5 get_ip() {
6 local iface="$1" ip=""
7 ip=$(ip -o -f inet addr show $iface)
8 ip=${ip%%/*}
9 ip=${ip##* }
10 }
11
12 iface_for_remote_addr() {
13 set -- $(ip -o route get to $1)
14 echo $5
15 }
16
17 iface_for_ip() {
18 set -- $(ip -o addr show to $1)
19 echo $2
20 }
21
22 iface_for_mac() {
23 local interface="" mac="$(echo $1 | sed 'y/ABCDEF/abcdef/')"
24 for interface in /sys/class/net/*; do
25 if [ $(cat $interface/address) = "$mac" ]; then
26 echo ${interface##*/}
27 fi
28 done
29 }
30
31 iface_has_link() {
32 local interface="$1" flags=""
33 [ -n "$interface" ] || return 2
34 interface="/sys/class/net/$interface"
35 [ -d "$interface" ] || return 2
36 flags=$(cat $interface/flags)
37 echo $(($flags|0x41)) > $interface/flags # 0x41: IFF_UP|IFF_RUNNING
38 [ "$(cat $interface/carrier)" = 1 ] || return 1
39 # XXX Do we need to reset the flags here? anaconda never bothered..
40 }
41
42 find_iface_with_link() {
43 local iface_path="" iface=""
44 for iface_path in /sys/class/net/*; do
45 iface=${iface_path##*/}
46 str_starts "$iface" "lo" && continue
47 if iface_has_link $iface; then
48 echo "$iface"
49 return 0
50 fi
51 done
52 return 1
53 }
54
55 # get the iface name for the given identifier - either a MAC, IP, or iface name
56 iface_name() {
57 case $1 in
58 ??:??:??:??:??:??|??-??-??-??-??-??) iface_for_mac $1 ;;
59 *:*:*|*.*.*.*) iface_for_ip $1 ;;
60 *) echo $1 ;;
61 esac
62 }
63
64 # list the configured interfaces
65 configured_ifaces() {
66 local IFACES="" iface_id="" rv=1
67 [ -e "/tmp/net.ifaces" ] && read IFACES < /tmp/net.ifaces
68 if { pidof udevd || pidof systemd-udevd; } > /dev/null; then
69 for iface_id in $IFACES; do
70 echo $(iface_name $iface_id)
71 rv=0
72 done
73 else
74 warn "configured_ifaces called before udev is running"
75 echo $IFACES
76 [ -n "$IFACES" ] && rv=0
77 fi
78 return $rv
79 }
80
81 all_ifaces_up() {
82 local iface="" IFACES=""
83 [ -e "/tmp/net.ifaces" ] && read IFACES < /tmp/net.ifaces
84 for iface in $IFACES; do
85 [ -e /tmp/net.$iface.up ] || return 1
86 done
87 }
88
89 get_netroot_ip() {
90 local prefix="" server="" rest=""
91 splitsep "$1" ":" prefix server rest
92 case $server in
93 [0-9]*\.[0-9]*\.[0-9]*\.[0-9]*) echo "$server"; return 0 ;;
94 esac
95 return 1
96 }
97
98 ip_is_local() {
99 strstr "$(ip route get $1 2>/dev/null)" " via "
100 }
101
102 ifdown() {
103 local netif="$1"
104 # ip down/flush ensures that routing info goes away as well
105 ip link set $netif down
106 ip addr flush dev $netif
107 echo "#empty" > /etc/resolv.conf
108 rm -f -- /tmp/net.$netif.did-setup
109 # TODO: send "offline" uevent?
110 }
111
112 setup_net() {
113 local netif="$1" f="" gw_ip="" netroot_ip="" iface="" IFACES=""
114 [ -e /tmp/net.$netif.did-setup ] && return
115 [ -e "/tmp/net.ifaces" ] && read IFACES < /tmp/net.ifaces
116 [ -z "$IFACES" ] && IFACES="$netif"
117 # run the scripts written by ifup
118 [ -e /tmp/net.$netif.gw ] && . /tmp/net.$netif.gw
119 [ -e /tmp/net.$netif.hostname ] && . /tmp/net.$netif.hostname
120 [ -e /tmp/net.$netif.override ] && . /tmp/net.$netif.override
121 [ -e /tmp/dhclient.$netif.dhcpopts ] && . /tmp/dhclient.$netif.dhcpopts
122 # set up resolv.conf
123 [ -e /tmp/net.$netif.resolv.conf ] && \
124 cp -f /tmp/net.$netif.resolv.conf /etc/resolv.conf
125
126 # Handle STP Timeout: arping the default gateway.
127 # (or the root server, if a) it's local or b) there's no gateway.)
128 # Note: This assumes that if no router is present the
129 # root server is on the same subnet.
130
131 # Get DHCP-provided router IP, or the cmdline-provided "gw=" argument
132 [ -n "$new_routers" ] && gw_ip=${new_routers%%,*}
133 [ -n "$gw" ] && gw_ip=$gw
134
135 # Get the "netroot" IP (if there's an IP address in there)
136 netroot_ip=$(get_netroot_ip $netroot)
137
138 # try netroot if it's local (or there's no gateway)
139 if ip_is_local $netroot_ip || [ -z "$gw_ip" ]; then
140 dest="$netroot_ip"
141 else
142 dest="$gw_ip"
143 fi
144
145 unset layer2
146 if [ -f /sys/class/net/$netif/device/layer2 ]; then
147 read layer2 < /sys/class/net/$netif/device/layer2
148 fi
149
150 if [ "$layer2" != "0" ] && [ -n "$dest" ] && ! arping -q -f -w 60 -I $netif $dest ; then
151 info "Resolving $dest via ARP on $netif failed"
152 fi
153 unset layer2
154
155 > /tmp/net.$netif.did-setup
156 }
157
158 save_netinfo() {
159 local netif="$1" IFACES="" f="" i=""
160 [ -e /tmp/net.ifaces ] && read IFACES < /tmp/net.ifaces
161 # Add $netif to the front of IFACES (if it's not there already).
162 set -- "$netif"
163 for i in $IFACES; do [ "$i" != "$netif" ] && set -- "$@" "$i"; done
164 IFACES="$*"
165 for i in $IFACES; do
166 for f in /tmp/dhclient.$i.*; do
167 [ -f $f ] && cp -f $f /tmp/net.${f#/tmp/dhclient.}
168 done
169 done
170 echo $IFACES > /tmp/.net.ifaces.new
171 mv /tmp/.net.ifaces.new /tmp/net.ifaces
172 }
173
174 set_ifname() {
175 local name="$1" mac="$2" num=-1 n=""
176 # if it's already set, return the existing name
177 for n in $(getargs ifname=); do
178 strstr "$n" "$mac" && echo ${n%%:*} && return
179 done
180 # otherwise, pick a new name and use that
181 while :; do
182 num=$(($num+1));
183 [ -e /sys/class/net/$name$num ] && continue
184 for n in $(getargs ifname=); do
185 [ "$name$num" = "${n%%:*}" ] && continue 2
186 done
187 break
188 done
189 echo "ifname=$name$num:$mac" >> /etc/cmdline.d/45-ifname.conf
190 echo "$name$num"
191 }
192
193 # pxelinux provides macaddr '-' separated, but we need ':'
194 fix_bootif() {
195 local macaddr=${1}
196 local IFS='-'
197 macaddr=$(for i in ${macaddr} ; do echo -n $i:; done)
198 macaddr=${macaddr%:}
199 # strip hardware type field from pxelinux
200 [ -n "${macaddr%??:??:??:??:??:??}" ] && macaddr=${macaddr#??:}
201 # return macaddr with lowercase alpha characters expected by udev
202 echo $macaddr | sed 'y/ABCDEF/abcdef/'
203 }
204
205 ibft_to_cmdline() {
206 local iface=""
207 modprobe -q iscsi_ibft
208 (
209 for iface in /sys/firmware/ibft/ethernet*; do
210 local mac="" dev=""
211 local dhcp="" ip="" gw="" mask="" hostname=""
212
213 [ -e ${iface}/mac ] || continue
214 mac=$(read a < ${iface}/mac; echo $a)
215 [ -z "$mac" ] && continue
216 dev=$(set_ifname ibft $mac)
217
218 [ -e /tmp/net.${dev}.has_ibft_config ] && continue
219
220 [ -e ${iface}/dhcp ] && dhcp=$(read a < ${iface}/dhcp; echo $a)
221
222 if [ -n "$dhcp" ]; then
223 echo "ip=$dev:dhcp"
224 elif [ -e ${iface}/ip-addr ]; then
225 [ -e ${iface}/ip-addr ] && ip=$(read a < ${iface}/ip-addr; echo $a)
226 # skip not assigned ip adresses
227 [ "$ip" = "0.0.0.0" ] && continue
228 [ -e ${iface}/gateway ] && gw=$(read a < ${iface}/gateway; echo $a)
229 [ -e ${iface}/subnet-mask ] && mask=$(read a < ${iface}/subnet-mask; echo $a)
230 [ -e ${iface}/hostname ] && hostname=$(read a < ${iface}/hostname; echo $a)
231 if [ -n "$ip" ] && [ -n "$mask" ]; then
232 echo "ip=$ip::$gw:$mask:$hostname:$dev:none"
233 else
234 warn "${iface} does not contain a valid iBFT configuration"
235 warn "ip-addr=$ip"
236 warn "gateway=$gw"
237 warn "subnet-mask=$mask"
238 warn "hostname=$hostname"
239 fi
240 else
241 info "${iface} does not contain a valid iBFT configuration"
242 ls -l ${iface} | vinfo
243 fi
244
245 if [ -e ${iface}/vlan ]; then
246 vlan=$(read a < ${iface}/vlan; echo $a)
247 if [ "$vlan" -ne "0" ]; then
248 case "$vlan" in
249 [0-9]*)
250 echo "vlan=$dev.$vlan:$dev"
251 ;;
252 *)
253 echo "vlan=$vlan:$dev"
254 ;;
255 esac
256 fi
257 fi
258
259 echo $mac > /tmp/net.${dev}.has_ibft_config
260 done
261 ) >> /etc/cmdline.d/40-ibft.conf
262 }
263
264 parse_iscsi_root()
265 {
266 local v
267 v=${1#iscsi:}
268
269 # extract authentication info
270 case "$v" in
271 *@*:*:*:*:*)
272 authinfo=${v%%@*}
273 v=${v#*@}
274 # allow empty authinfo to allow having an @ in iscsi_target_name like this:
275 # netroot=iscsi:@192.168.1.100::3260::iqn.2009-01.com.example:testdi@sk
276 if [ -n "$authinfo" ]; then
277 OLDIFS="$IFS"
278 IFS=:
279 set $authinfo
280 IFS="$OLDIFS"
281 if [ $# -gt 4 ]; then
282 warn "Wrong authentication info in iscsi: parameter!"
283 return 1
284 fi
285 iscsi_username=$1
286 iscsi_password=$2
287 if [ $# -gt 2 ]; then
288 iscsi_in_username=$3
289 iscsi_in_password=$4
290 fi
291 fi
292 ;;
293 esac
294
295 # extract target ip
296 case "$v" in
297 [[]*[]]:*)
298 iscsi_target_ip=${v#[[]}
299 iscsi_target_ip=${iscsi_target_ip%%[]]*}
300 v=${v#[[]$iscsi_target_ip[]]:}
301 ;;
302 *)
303 iscsi_target_ip=${v%%[:]*}
304 v=${v#$iscsi_target_ip:}
305 ;;
306 esac
307
308 # extract target name
309 case "$v" in
310 *:iqn.*)
311 iscsi_target_name=iqn.${v##*:iqn.}
312 v=${v%:iqn.*}:
313 ;;
314 *:eui.*)
315 iscsi_target_name=iqn.${v##*:eui.}
316 v=${v%:iqn.*}:
317 ;;
318 *:naa.*)
319 iscsi_target_name=iqn.${v##*:naa.}
320 v=${v%:iqn.*}:
321 ;;
322 *)
323 warn "Invalid iscii target name, should begin with 'iqn.' or 'eui.' or 'naa.'"
324 return 1
325 ;;
326 esac
327
328 # parse the rest
329 OLDIFS="$IFS"
330 IFS=:
331 set $v
332 IFS="$OLDIFS"
333
334 iscsi_protocol=$1; shift # ignored
335 iscsi_target_port=$1; shift
336 if [ $# -eq 3 ]; then
337 iscsi_iface_name=$1; shift
338 fi
339 if [ $# -eq 2 ]; then
340 iscsi_netdev_name=$1; shift
341 fi
342 iscsi_lun=$1; shift
343 if [ $# -ne 0 ]; then
344 warn "Invalid parameter in iscsi: parameter!"
345 return 1
346 fi
347 }
348
349 ip_to_var() {
350 local v=${1}:
351 local i
352 set --
353 while [ -n "$v" ]; do
354 if [ "${v#\[*:*:*\]:}" != "$v" ]; then
355 # handle IPv6 address
356 i="${v%%\]:*}"
357 i="${i##\[}"
358 set -- "$@" "$i"
359 v=${v#\[$i\]:}
360 else
361 set -- "$@" "${v%%:*}"
362 v=${v#*:}
363 fi
364 done
365
366 unset ip srv gw mask hostname dev autoconf macaddr mtu
367 case $# in
368 0) autoconf="error" ;;
369 1) autoconf=$1 ;;
370 2) [ -n "$1" ] && dev=$1; [ -n "$2" ] && autoconf=$2 ;;
371 3) [ -n "$1" ] && dev=$1; [ -n "$2" ] && autoconf=$2; [ -n "$3" ] && mtu=$3 ;;
372 4) [ -n "$1" ] && dev=$1; [ -n "$2" ] && autoconf=$2; [ -n "$3" ] && mtu=$3; [ -n "$4" ] && macaddr=$4 ;;
373 *) [ -n "$1" ] && ip=$1; [ -n "$2" ] && srv=$2; [ -n "$3" ] && gw=$3; [ -n "$4" ] && mask=$4;
374 [ -n "$5" ] && hostname=$5; [ -n "$6" ] && dev=$6; [ -n "$7" ] && autoconf=$7; [ -n "$8" ] && mtu=$8;
375 if [ -n "${9}" -a -n "${10}" -a -n "${11}" -a -n "${12}" -a -n "${13}" -a -n "${14}" ]; then
376 macaddr="${9}:${10}:${11}:${12}:${13}:${14}"
377 fi
378 ;;
379 esac
380
381 # ip=<ipv4-address> means anaconda-style static config argument cluster:
382 # ip=<ip> gateway=<gw> netmask=<nm> hostname=<host> mtu=<mtu>
383 # ksdevice={link|bootif|ibft|<MAC>|<ifname>}
384 if strstr "$autoconf" "*.*.*.*"; then
385 ip="$autoconf"
386 gw=$(getarg gateway=)
387 mask=$(getarg netmask=)
388 hostname=$(getarg hostname=)
389 dev=$(getarg ksdevice=)
390 autoconf="none"
391 mtu=$(getarg mtu=)
392
393 # handle special values for ksdevice
394 case "$dev" in
395 bootif|BOOTIF) dev=$(fix_bootif $(getarg BOOTIF=)) ;;
396 link) dev="" ;; # FIXME: do something useful with this
397 ibft) dev="" ;; # ignore - ibft is handled elsewhere
398 esac
399 fi
400 }
401
402 parse_ifname_opts() {
403 local IFS=:
404 set $1
405
406 case $# in
407 7)
408 ifname_if=$1
409 # udev requires MAC addresses to be lower case
410 ifname_mac=$(echo $2:$3:$4:$5:$6:$7 | sed 'y/ABCDEF/abcdef/')
411 ;;
412 *)
413 die "Invalid arguments for ifname="
414 ;;
415 esac
416
417 case $ifname_if in
418 eth[0-9]|eth[0-9][0-9]|eth[0-9][0-9][0-9]|eth[0-9][0-9][0-9][0-9])
419 warn "ifname=$ifname_if uses the kernel name space for interfaces"
420 warn "This can fail for multiple network interfaces and is discouraged!"
421 warn "Please use a custom name like \"netboot\" or \"bluesocket\""
422 warn "or use biosdevname and no ifname= at all."
423 ;;
424 esac
425
426 }
427
428 # some network driver need long time to initialize, wait before it's ready.
429 wait_for_if_link() {
430 local cnt=0
431 local li
432 while [ $cnt -lt 600 ]; do
433 li=$(ip -o link show dev $1 2>/dev/null)
434 [ -n "$li" ] && return 0
435 sleep 0.1
436 cnt=$(($cnt+1))
437 done
438 return 1
439 }
440
441 wait_for_if_up() {
442 local cnt=0
443 local li
444 while [ $cnt -lt 200 ]; do
445 li=$(ip -o link show up dev $1)
446 [ -n "$li" ] && return 0
447 sleep 0.1
448 cnt=$(($cnt+1))
449 done
450 return 1
451 }
452
453 wait_for_route_ok() {
454 local cnt=0
455 while [ $cnt -lt 200 ]; do
456 li=$(ip route show)
457 [ -n "$li" ] && [ -z "${li##*$1*}" ] && return 0
458 sleep 0.1
459 cnt=$(($cnt+1))
460 done
461 return 1
462 }
463
464 wait_for_ipv6_auto() {
465 local cnt=0
466 local li
467 while [ $cnt -lt 400 ]; do
468 li=$(ip -6 addr show dev $1)
469 strstr "$li" "dynamic" && return 0
470 sleep 0.1
471 cnt=$(($cnt+1))
472 done
473 return 1
474 }
475
476 linkup() {
477 wait_for_if_link $1 2>/dev/null\
478 && ip link set $1 up 2>/dev/null\
479 && wait_for_if_up $1 2>/dev/null
480 }
481
482 type hostname >/dev/null 2>&1 || \
483 hostname() {
484 cat /proc/sys/kernel/hostname
485 }