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
# 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

View File

@ -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

View File

@ -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