network: refactor stuff from netroot/parse-ip-opts to net-lib

Add new functions: all_ifaces_up, get_netroot_ip, ip_is_local, ifdown,
setup_net, set_ifname, ibft_to_cmdline

Use them in netroot.sh and parse-ip-opts.sh.

There's also a couple little unrelated cleanups.
master
Will Woods 2012-03-06 18:25:24 -05:00 committed by Harald Hoyer
parent 4d518aec86
commit 25aa3c5a6e
3 changed files with 120 additions and 105 deletions

View File

@ -31,3 +31,111 @@ iface_has_link() {
[ "$(cat $interface/carrier)" = 1 ] || return 1
# XXX Do we need to reset the flags here? anaconda never bothered..
}

all_ifaces_up() {
local iface="" IFACES=""
[ -e "/tmp/net.ifaces" ] && read IFACES < /tmp/net.ifaces
for iface in $IFACES; do
[ -e /tmp/net.$iface.up ] || return 1
done
}

get_netroot_ip() {
local prefix="" server="" rest=""
splitsep "$1" ":" prefix server rest
case $server in
[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*) echo "$server"; return 0 ;;
esac
return 1
}

ip_is_local() {
strstr "$(ip route get $1 2>/dev/null)" " via "
}

ifdown() {
local netif="$1"
# ip down/flush ensures that routing info goes away as well
ip link set $netif down
ip addr flush dev $netif
echo "#empty" > /etc/resolv.conf
# TODO: send "offline" uevent?
}

setup_net() {
local netif="$1" f="" gw_ip="" netroot_ip="" iface="" IFACES=""
[ -e /tmp/net.$netif.up ] || return 1
[ -e "/tmp/net.ifaces" ] && read IFACES < /tmp/net.ifaces
[ -z "$IFACES" ] && IFACES="$netif"
for iface in $IFACES ; do
. /tmp/net.$iface.up
done
# run the scripts written by ifup
[ -e /tmp/net.$netif.gw ] && . /tmp/net.$netif.gw
[ -e /tmp/net.$netif.hostname ] && . /tmp/net.$netif.hostname
[ -e /tmp/net.$netif.override ] && . /tmp/net.$netif.override
[ -e /tmp/dhclient.$netif.dhcpopts ] && . /tmp/dhclient.$netif.dhcpopts
# set up resolv.conf
[ -e /tmp/net.$netif.resolv.conf ] && \
cp -f /tmp/net.$netif.resolv.conf /etc/resolv.conf

# Handle STP Timeout: arping the default gateway.
# (or the root server, if a) it's local or b) there's no gateway.)
# Note: This assumes that if no router is present the
# root server is on the same subnet.

# Get DHCP-provided router IP, or the cmdline-provided "gw=" argument
[ -n "$new_routers" ] && gw_ip=${new_routers%%,*}
[ -n "$gw" ] && gw_ip=$gw

# Get the "netroot" IP (if there's an IP address in there)
netroot_ip=$(get_netroot_ip $netroot)

# try netroot if it's local (or there's no gateway)
if ip_is_local $netroot_ip || [ -z "$gw_ip" ]; then
dest="$netroot_ip"
else
dest="$gw_ip"
fi
if [ -n "$dest" ] && ! arping -q -f -w 60 -I $netif $dest ; then
info "Resolving $dest via ARP on $netif failed"
fi
}

set_ifname() {
local name="$1" mac="$2" num=0 n=""
# if it's already set, return the existing name
for n in $(getargs ifname=); do
strstr "$n" "$mac" && echo ${n%%:*} && return
done
# otherwise, pick a new name and use that
while [ -e /sys/class/$name$num ]; do num=$(($num+1)); done
echo "ifname=$name$num:$mac" >> /etc/cmdline.d/45-ifname.conf
echo "$name$num"
}

ibft_to_cmdline() {
local iface="" mac="" dev=""
local dhcp="" ip="" gw="" mask="" hostname=""
modprobe -q iscsi_ibft
(
for iface in /sys/firmware/ibft/ethernet*; do
[ -e ${iface}/mac ] || continue
mac=$(read a < ${iface}/mac; echo $a)
[ -z "$ifname_mac" ] && continue
dev=$(set_ifname ibft $ifname_mac)
dhcp=$(read a < ${iface}/dhcp; echo $a)
if [ -n "$dhcp" ]; then
echo "ip=$dev:dhcp"
else
ip=$(read a < ${iface}/ip-addr; echo $a)
gw=$(read a < ${iface}/gateway; echo $a)
mask=$(read a < ${iface}/subnet-mask; echo $a)
hostname=$(read a < ${iface}/hostname; echo $a)
echo "ip=$ip::$gw:$mask:$hostname:$dev:none"
fi
done
) >> /etc/cmdline.d/40-ibft.conf
# reread cmdline
unset CMDLINE
}

View File

@ -3,14 +3,12 @@
# ex: ts=8 sw=4 sts=4 et filetype=sh

PATH=/usr/sbin:/usr/bin:/sbin:/bin
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
command -v getarg >/dev/null || . /lib/dracut-lib.sh
command -v setup_net >/dev/null || . /lib/net-lib.sh

# Huh? Empty $1?
[ -z "$1" ] && exit 1

# Huh? No interface config?
[ ! -e /tmp/net.$1.up ] && exit 1

# [ ! -z $2 ] means this is for manually bringing up network
# instead of real netroot; If It's called without $2, then there's
# no sense in doing something if no (net)root info is available
@ -23,10 +21,7 @@ fi
# Let's see if we have to wait for other interfaces
# Note: exit works just fine, since the last interface to be
# online'd should see all files
[ -e "/tmp/net.ifaces" ] && read IFACES < /tmp/net.ifaces
for iface in $IFACES ; do
[ -e /tmp/net.$iface.up ] || exit 1
done
all_ifaces_up || exit 1

# Set or override primary interface
netif=$1
@ -78,62 +73,13 @@ if [ -z "$2" ]; then
fi

# We're here, so we can assume that upping interfaces is now ok
[ -z "$IFACES" ] && IFACES="$netif"
for iface in $IFACES ; do
. /tmp/net.$iface.up
done

[ -e /tmp/net.$netif.gw ] && . /tmp/net.$netif.gw
[ -e /tmp/net.$netif.hostname ] && . /tmp/net.$netif.hostname
[ -e /tmp/net.$netif.resolv.conf ] && cp -f /tmp/net.$netif.resolv.conf /etc/resolv.conf

# Load interface options
[ -e /tmp/net.$netif.override ] && . /tmp/net.$netif.override
[ -e /tmp/dhclient.$netif.dhcpopts ] && . /tmp/dhclient.$netif.dhcpopts

# Handle STP Timeout: arping the default router if root server is
# unknown or not local, or if not available the root server.
# Note: This assumes that if no router is present the
# root server is on the same subnet.
#
# TODO There's some netroot variants that don't (yet) have their
# server-ip netroot

# Get router IP if set
[ -n "$new_routers" ] && gw_ip=${new_routers%%,*}
[ -n "$gw" ] && gw_ip=$gw
# Get root server IP if set
if [ -n "$netroot" ]; then
dummy=${netroot#*:}
dummy=${dummy%%:*}
case "$dummy" in
[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*) netroot_ip=$dummy;;
esac
fi
# Default arping dest to router
dest="$gw_ip"
# Change to arping root server if appropriate
if [ -n "$netroot_ip" ]; then
if [ -z "$dest" ]; then
# no gateway so check root server
dest="$netroot_ip"
else
r=$(ip route get "$netroot_ip")
if ! strstr "$r" ' via ' ; then
# local root server, so don't arping gateway
dest="$netroot_ip"
fi
fi
fi
if [ -n "$dest" ] && ! arping -q -f -w 60 -I $netif $dest ; then
dinfo "Resolving $dest via ARP on $netif failed"
fi
setup_net $netif

# exit in case manually bring up network
[ -n "$2" ] && exit 0

# Source netroot hooks before we start the handler
source_all $hookdir/netroot
source_hook netroot

# Run the handler; don't store the root, it may change from device to device
# XXX other variables to export?
@ -149,11 +95,6 @@ if $handler $netif $netroot $NEWROOT; then
else
warn "Mounting root via '$netif' failed"
# If we're trying with multiple interfaces, put that one down.
# ip down/flush ensures that routeing info goes away as well
if [ -z "$BOOTDEV" ] ; then
ip link set $netif down
ip addr flush dev $netif
echo "#empty" > /etc/resolv.conf
fi
[ -z "$BOOTDEV" ] && ifdown $netif
fi
exit 0

View File

@ -14,7 +14,8 @@
# routing,dns,dhcp-options,etc.
#

type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
command -v getarg >/dev/null || . /lib/dracut-lib.sh
command -v ibft_to_cmdline >/dev/null || . /lib/net-lib.sh

# Check if ip= lines should be used
if getarg ip= >/dev/null ; then
@ -52,50 +53,15 @@ if [ -n "$NEEDBOOTDEV" ] ; then
[ -z "$BOOTDEV" ] && die "Bootdev argument is empty"
fi

if [ "ibft" = "$(getarg ip=)" ]; then
modprobe iscsi_ibft
num=0
(
for iface in /sys/firmware/ibft/ethernet*; do
[ -e ${iface}/mac ] || continue
ifname_mac=$(read a < ${iface}/mac; echo $a)
[ -z "$ifname_mac" ] && continue
unset dev
for ifname in $(getargs ifname=); do
if strstr "$ifname" "$ifname_mac"; then
dev=${ifname%%:*}
break
fi
done
if [ -z "$dev" ]; then
ifname_if=ibft$num
num=$(( $num + 1 ))
echo "ifname=$ifname_if:$ifname_mac"
dev=$ifname_if
fi

dhcp=$(read a < ${iface}/dhcp; echo $a)
if [ -n "$dhcp" ]; then
echo "ip=$dev:dhcp"
else
ip=$(read a < ${iface}/ip-addr; echo $a)
gw=$(read a < ${iface}/gateway; echo $a)
mask=$(read a < ${iface}/subnet-mask; echo $a)
hostname=$(read a < ${iface}/hostname; echo $a)
echo "ip=$ip::$gw:$mask:$hostname:$dev:none"
fi
done
) >> /etc/cmdline
# reread cmdline
unset CMDLINE
fi
# If ibft is requested, read ibft vals and write ip=XXX cmdline args
[ "ibft" = "$(getarg ip=)" ] && ibft_to_cmdline

# Check ip= lines
# XXX Would be nice if we could errorcheck ip addresses here as well
for p in $(getargs ip=); do
ip_to_var $p

# skip ibft
# skip ibft since we did it above
[ "$autoconf" = "ibft" ] && continue

# We need to have an ip= line for the specified bootdev
@ -111,7 +77,7 @@ for p in $(getargs ip=); do
case $autoconf in
error) die "Error parsing option 'ip=$p'";;
bootp|rarp|both) die "Sorry, ip=$autoconf is currenty unsupported";;
none|off) \
none|off)
[ -z "$ip" ] && \
die "For argument 'ip=$p'\nValue '$autoconf' without static configuration does not make sense"
[ -z "$mask" ] && \