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
Philippe Seewer 2009-06-16 20:21:41 +02:00
parent 3029be4df8
commit db8158439d
3 changed files with 71 additions and 76 deletions

View File

@ -1,22 +1,4 @@
#!/bin/sh -e #!/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() { setup_interface() {
ip=$new_ip_address ip=$new_ip_address
@ -32,23 +14,23 @@ setup_interface() {
[ -f /tmp/net.$netif.override ] && . /tmp/net.$netif.override [ -f /tmp/net.$netif.override ] && . /tmp/net.$netif.override


if [ -n "$mtu" ] ; then if [ -n "$mtu" ] ; then
run ip link set $netif down echo ip link set $netif down
run ip link set $netif mtu $mtu echo ip link set $netif mtu $mtu
run ip link set $netif up echo ip link set $netif up
fi fi > /tmp/net.$netif.up


run ip addr add $ip${mask:+/$mask} ${bcast:+broadcast $bcast} dev $netif echo ip addr add $ip${mask:+/$mask} ${bcast:+broadcast $bcast} dev $netif >> /tmp/net.$netif.up
[ -n "$gw" ] && run ip route add default via $gw
if [ -n "${search}${domain}" -a -n "$namesrv" ] ; then [ -n "$gw" ] && echo ip route add default via $gw dev $netif > /tmp/net.$netif.gw
echo search $search $domain > /etc/resolv.conf
[ -n "${search}${domain}" ] && echo search $search $domain > /tmp/net.$netif.resolv.conf
if [ -n "$namesrv" ] ; then
for s in $namesrv; do for s in $namesrv; do
echo nameserver $s >> /etc/resolv.conf echo nameserver $s
done done
fi fi >> /tmp/net.$netif.resolv.conf
if [ ! -e /tmp/hostname.set ] ; then
[ -n "$hostname" ] && mknod /tmp/hostname.set p && run hostname $hostname [ -n "$hostname" ] && echo hostname $hostname > /tmp/net.$netif.hostname
fi
:
} }


PATH=$PATH:/sbin:/usr/sbin PATH=$PATH:/sbin:/usr/sbin
@ -64,15 +46,12 @@ fi
# Huh? Interface configured? # Huh? Interface configured?
[ -f "/tmp/net.$netif.up" ] && exit 0 [ -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 # We already need a set netif here
netif=$interface netif=$interface


case $reason in case $reason in
PREINIT) PREINIT)
run ip link set $netif up ip link set $netif up
;; ;;
BOUND) BOUND)
setup_interface setup_interface
@ -80,10 +59,9 @@ case $reason in
[ "${line#new_}" = "$line" ] && continue [ "${line#new_}" = "$line" ] && continue
echo "$line" echo "$line"
done >/tmp/dhclient.$netif.dhcpopts done >/tmp/dhclient.$netif.dhcpopts
>/tmp/net.$netif.up echo online > /sys/class/net/$netif/uevent
echo online > /sys/class/net/$netif/uevent ;; ;;
*) ;; *) ;;
esac esac


trap - EXIT
exit 0 exit 0

View File

@ -1,40 +1,47 @@
#!/bin/sh #!/bin/sh
#
# We don't need to check for ip= errors here, that is handled by the
# cmdline parser script
#


die() { # Sadly there's no easy way to split ':' separated lines into variables
echo $netif: "$@" 1>&2 ip_to_var() {
exit 1 local v=${1}:
} set --

while [ -n "$v" ]; do
do_static() { set -- "$@" "${v%%:*}"
[ -n "$ip" ] || die "static: need IP address" v=${v#*:}
[ -n "$mask" ] || { done
net=${ip%%.*}
mask=255.0.0.0 unset ip srv gw mask hostname dev autoconf
[ $net -ge 128 ] && mask=255.255.0.0 case $# in
[ $net -ge 192 ] && mask=255.255.255.0 0) autoconf="error" ;;
} 1) autoconf=$1 ;;
ip addr add $ip/$mask dev $netif || die "static: setting IP $ip/$mask" 2) dev=$1; autoconf=$2 ;;
[ -n "$gw" ] && { *) ip=$1; srv=$2; gw=$3; mask=$4; hostname=$5; dev=$6; autoconf=$7 ;;
ip route add default via $gw dev $netif || esac
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
} }


# Run dhclient
do_dhcp() { do_dhcp() {
# /sbin/dhclient-script will mark the netif up and generate the online # /sbin/dhclient-script will mark the netif up and generate the online
# event for nfsroot # event for nfsroot
# XXX add -V vendor class and option parsing per kernel # 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 PATH=$PATH:/sbin:/usr/sbin
@ -82,7 +89,7 @@ for p in $CMDLINE; do
ip_to_var ${p#ip=} ip_to_var ${p#ip=}
# If this option isn't directed at our interface, skip it # If this option isn't directed at our interface, skip it
[ "$dev" = "$netif" ] || continue [ -n "$dev" ] && [ "$dev" != "$netif" ] && continue


# Store config for later use # Store config for later use
for i in ip srv gw mask hostname; do for i in ip srv gw mask hostname; do
@ -90,12 +97,9 @@ for p in $CMDLINE; do
done > /tmp/net.$netif.override done > /tmp/net.$netif.override


case $autoconf in case $autoconf in
static) do_static ;;
dhcp|on|any) do_dhcp ;; dhcp|on|any) do_dhcp ;;
bootp|rarp|both) die "autoconfig type $autoconf is not supported" ;; *) do_static ;;
''|none|off) ;; esac
esac break
break done
done
fi
exit 0 exit 0

View File

@ -62,6 +62,12 @@ if [ -z "$netroot" ] || [ ! -e "$handler" ] ; then
die "No handler for netroot type '$netroot'" die "No handler for netroot type '$netroot'"
fi 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 netroot hooks before we start the handler
source_all netroot source_all netroot


@ -74,5 +80,12 @@ if $handler $netif $netroot $NEWROOT; then


# Save used netif for later use # Save used netif for later use
echo $netif > /tmp/net.bootdev 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 fi
exit 0 exit 0