323 lines
11 KiB
Diff
323 lines
11 KiB
Diff
|
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" ] && \
|