multnic support: move actual interface configuration to netroot
Instead of configuring devices when they are ready, ifup and dhclient-script write script files which are then sourced by netroot. This solves the problem of having multiple interfaces and not knowing which one to use for dhcp or default route. This way, netroot (which is serialized anyway) configures the interface before calling the root handler and deconfigures it if the handler failed. Example: root=nfs:server:path and ip=dhcp with eth0 and eth1 receiving a dhcp reply, but eth0 is the correct one to use. Assuming eth1 is the first to receive the dhcp-reply, netroot starts and configures eth1. nfsroot is run but fails, so eth1 is deconfigured. If eth0 has received a dhcp-reply (or not, then we wait) the other locked netroot process starts and tries with eth0 and succeeds.master
parent
3029be4df8
commit
db8158439d
|
@ -1,22 +1,4 @@
|
|||
#!/bin/sh -e
|
||||
# very simple dhclient-script. All it cares about is bringing the interface
|
||||
# up, and it does not even try to do anything else.
|
||||
|
||||
LOG=/tmp/dhclient.$$.log
|
||||
ERR=/tmp/network.$$.err
|
||||
|
||||
log_err() {
|
||||
# avoid the need for cat on the image
|
||||
echo "On $netif, the following command:" > $ERR
|
||||
echo " " "$CMD" >> $ERR
|
||||
echo "had errors:" >> $ERR
|
||||
while read line; do echo " $line"; done < $LOG >> $ERR
|
||||
}
|
||||
|
||||
run() {
|
||||
CMD="$@"
|
||||
"$@" >> $LOG 2>&1
|
||||
}
|
||||
|
||||
setup_interface() {
|
||||
ip=$new_ip_address
|
||||
|
@ -32,23 +14,23 @@ setup_interface() {
|
|||
[ -f /tmp/net.$netif.override ] && . /tmp/net.$netif.override
|
||||
|
||||
if [ -n "$mtu" ] ; then
|
||||
run ip link set $netif down
|
||||
run ip link set $netif mtu $mtu
|
||||
run ip link set $netif up
|
||||
fi
|
||||
echo ip link set $netif down
|
||||
echo ip link set $netif mtu $mtu
|
||||
echo ip link set $netif up
|
||||
fi > /tmp/net.$netif.up
|
||||
|
||||
run ip addr add $ip${mask:+/$mask} ${bcast:+broadcast $bcast} dev $netif
|
||||
[ -n "$gw" ] && run ip route add default via $gw
|
||||
if [ -n "${search}${domain}" -a -n "$namesrv" ] ; then
|
||||
echo search $search $domain > /etc/resolv.conf
|
||||
echo ip addr add $ip${mask:+/$mask} ${bcast:+broadcast $bcast} dev $netif >> /tmp/net.$netif.up
|
||||
|
||||
[ -n "$gw" ] && echo ip route add default via $gw dev $netif > /tmp/net.$netif.gw
|
||||
|
||||
[ -n "${search}${domain}" ] && echo search $search $domain > /tmp/net.$netif.resolv.conf
|
||||
if [ -n "$namesrv" ] ; then
|
||||
for s in $namesrv; do
|
||||
echo nameserver $s >> /etc/resolv.conf
|
||||
echo nameserver $s
|
||||
done
|
||||
fi
|
||||
if [ ! -e /tmp/hostname.set ] ; then
|
||||
[ -n "$hostname" ] && mknod /tmp/hostname.set p && run hostname $hostname
|
||||
fi
|
||||
:
|
||||
fi >> /tmp/net.$netif.resolv.conf
|
||||
|
||||
[ -n "$hostname" ] && echo hostname $hostname > /tmp/net.$netif.hostname
|
||||
}
|
||||
|
||||
PATH=$PATH:/sbin:/usr/sbin
|
||||
|
@ -64,15 +46,12 @@ fi
|
|||
# Huh? Interface configured?
|
||||
[ -f "/tmp/net.$netif.up" ] && exit 0
|
||||
|
||||
# save offending commands and let udev move on if we have an error
|
||||
trap 'log_err; exit 0' EXIT
|
||||
|
||||
# We already need a set netif here
|
||||
netif=$interface
|
||||
|
||||
case $reason in
|
||||
PREINIT)
|
||||
run ip link set $netif up
|
||||
ip link set $netif up
|
||||
;;
|
||||
BOUND)
|
||||
setup_interface
|
||||
|
@ -80,10 +59,9 @@ case $reason in
|
|||
[ "${line#new_}" = "$line" ] && continue
|
||||
echo "$line"
|
||||
done >/tmp/dhclient.$netif.dhcpopts
|
||||
>/tmp/net.$netif.up
|
||||
echo online > /sys/class/net/$netif/uevent ;;
|
||||
echo online > /sys/class/net/$netif/uevent
|
||||
;;
|
||||
*) ;;
|
||||
esac
|
||||
|
||||
trap - EXIT
|
||||
exit 0
|
||||
|
|
|
@ -1,40 +1,47 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# We don't need to check for ip= errors here, that is handled by the
|
||||
# cmdline parser script
|
||||
#
|
||||
|
||||
die() {
|
||||
echo $netif: "$@" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
do_static() {
|
||||
[ -n "$ip" ] || die "static: need IP address"
|
||||
[ -n "$mask" ] || {
|
||||
net=${ip%%.*}
|
||||
mask=255.0.0.0
|
||||
[ $net -ge 128 ] && mask=255.255.0.0
|
||||
[ $net -ge 192 ] && mask=255.255.255.0
|
||||
}
|
||||
ip addr add $ip/$mask dev $netif || die "static: setting IP $ip/$mask"
|
||||
[ -n "$gw" ] && {
|
||||
ip route add default via $gw dev $netif ||
|
||||
die "static: setting default route via $gw"
|
||||
}
|
||||
ip link set $netif up
|
||||
[ -e /tmp/hostname.set ] || {
|
||||
[ -n "$hostname" ] && mknod /tmp/hostname.set p 2>/dev/null &&
|
||||
hostname $hostname
|
||||
}
|
||||
[ -n "$srv" ] &&
|
||||
echo "new_dhcp_server_identifier=$srv" > /tmp/dhclient.$netif.dhcpopts
|
||||
|
||||
>/tmp/net.$netif.up
|
||||
echo online > /sys/class/net/$netif/uevent
|
||||
# Sadly there's no easy way to split ':' separated lines into variables
|
||||
ip_to_var() {
|
||||
local v=${1}:
|
||||
set --
|
||||
while [ -n "$v" ]; do
|
||||
set -- "$@" "${v%%:*}"
|
||||
v=${v#*:}
|
||||
done
|
||||
|
||||
unset ip srv gw mask hostname dev autoconf
|
||||
case $# in
|
||||
0) autoconf="error" ;;
|
||||
1) autoconf=$1 ;;
|
||||
2) dev=$1; autoconf=$2 ;;
|
||||
*) ip=$1; srv=$2; gw=$3; mask=$4; hostname=$5; dev=$6; autoconf=$7 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Run dhclient
|
||||
do_dhcp() {
|
||||
# /sbin/dhclient-script will mark the netif up and generate the online
|
||||
# event for nfsroot
|
||||
# XXX add -V vendor class and option parsing per kernel
|
||||
dhclient -1 -q -cf /etc/dhclient.conf -pf /tmp/dhclient.$netif.pid -lf /tmp/dhclient.$netif.lease $netif
|
||||
dhclient -1 -q -cf /sbin/dhclient.conf -pf /tmp/dhclient.$netif.pid -lf /tmp/dhclient.$netif.lease $netif
|
||||
}
|
||||
|
||||
# Handle static ip configuration
|
||||
do_static() {
|
||||
{
|
||||
echo ip link set $netif up
|
||||
echo ip addr flush dev $netif
|
||||
echo ip addr add $ip/$mask dev $netif
|
||||
} > /tmp/net.$netif.up
|
||||
|
||||
[ -n "$gw" ] && echo ip route add default via $gw dev $netif > /tmp/net.$netif.gw
|
||||
[ -n "$hostname" ] && echo hostname $hostname > /tmp/net.$netif.hostname
|
||||
|
||||
echo online > /sys/class/net/$netif/uevent
|
||||
}
|
||||
|
||||
PATH=$PATH:/sbin:/usr/sbin
|
||||
|
@ -82,7 +89,7 @@ for p in $CMDLINE; do
|
|||
ip_to_var ${p#ip=}
|
||||
|
||||
# If this option isn't directed at our interface, skip it
|
||||
[ "$dev" = "$netif" ] || continue
|
||||
[ -n "$dev" ] && [ "$dev" != "$netif" ] && continue
|
||||
|
||||
# Store config for later use
|
||||
for i in ip srv gw mask hostname; do
|
||||
|
@ -90,12 +97,9 @@ for p in $CMDLINE; do
|
|||
done > /tmp/net.$netif.override
|
||||
|
||||
case $autoconf in
|
||||
static) do_static ;;
|
||||
dhcp|on|any) do_dhcp ;;
|
||||
bootp|rarp|both) die "autoconfig type $autoconf is not supported" ;;
|
||||
''|none|off) ;;
|
||||
esac
|
||||
break
|
||||
done
|
||||
fi
|
||||
*) do_static ;;
|
||||
esac
|
||||
break
|
||||
done
|
||||
exit 0
|
||||
|
|
|
@ -62,6 +62,12 @@ if [ -z "$netroot" ] || [ ! -e "$handler" ] ; then
|
|||
die "No handler for netroot type '$netroot'"
|
||||
fi
|
||||
|
||||
# We're here, so we can assume that upping interfaces is now ok
|
||||
. /tmp/net.$netif.up
|
||||
[ -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
|
||||
|
||||
# Source netroot hooks before we start the handler
|
||||
source_all netroot
|
||||
|
||||
|
@ -74,5 +80,12 @@ if $handler $netif $netroot $NEWROOT; then
|
|||
|
||||
# Save used netif for later use
|
||||
echo $netif > /tmp/net.bootdev
|
||||
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
|
||||
ip link set $netif down
|
||||
ip addr flush dev $netif
|
||||
echo "#empty" > /etc/resolv.conf
|
||||
fi
|
||||
exit 0
|
||||
|
|
Loading…
Reference in New Issue