From 25aa3c5a6eb48d14972b5c658cc7231d8f100ea8 Mon Sep 17 00:00:00 2001 From: Will Woods Date: Tue, 6 Mar 2012 18:25:24 -0500 Subject: [PATCH] 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. --- modules.d/40network/net-lib.sh | 108 ++++++++++++++++++++++++++++++++++ modules.d/40network/netroot.sh | 71 ++-------------------- modules.d/40network/parse-ip-opts.sh | 46 ++------------- 3 files changed, 120 insertions(+), 105 deletions(-) diff --git a/modules.d/40network/net-lib.sh b/modules.d/40network/net-lib.sh index e3987a4..e51ce94 100644 --- a/modules.d/40network/net-lib.sh +++ b/modules.d/40network/net-lib.sh @@ -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 +} diff --git a/modules.d/40network/netroot.sh b/modules.d/40network/netroot.sh index c5ee84c..ac1c215 100755 --- a/modules.d/40network/netroot.sh +++ b/modules.d/40network/netroot.sh @@ -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 diff --git a/modules.d/40network/parse-ip-opts.sh b/modules.d/40network/parse-ip-opts.sh index c97941e..7851329 100755 --- a/modules.d/40network/parse-ip-opts.sh +++ b/modules.d/40network/parse-ip-opts.sh @@ -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" ] && \