Contents of /mcore-src/trunk/mcore-tools/dracut/net-lib.sh
Parent Directory | 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)
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 | } |