From 25aa3c5a6eb48d14972b5c658cc7231d8f100ea8 Mon Sep 17 00:00:00 2001
From: Will Woods <wwoods@redhat.com>
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" ] && \