# Write udev rules
{
-# BOOTIF says everything, use only that one
+ # BOOTIF says everything, use only that one
BOOTIF=$(getarg 'BOOTIF=')
if [ -n "$BOOTIF" ] ; then
BOOTIF=$(fix_bootif "$BOOTIF")
printf 'ACTION=="add", SUBSYSTEM=="net", ATTR{address}=="%s", RUN+="/sbin/ifup $env{INTERFACE}"\n' "$BOOTIF"
- else
+
+ # If we have to handle multiple interfaces, handle only them.
+ elif [ -n "$IFACES" ] ; then
+ for iface in $IFACES ; do
+ printf 'ACTION=="add", SUBSYSTEM=="net", KERNEL=="%s", RUN+="/sbin/ifup $env{INTERFACE}"\n' "$iface"
+ done
+
+ # Default: We don't know the interface to use, handle all
+ else
printf 'ACTION=="add", SUBSYSTEM=="net", RUN+="/sbin/ifup $env{INTERFACE}"\n'
fi
[ -d $NEWROOT/proc ] && exit 0
[ -z "$netroot" ] && exit 1
+# 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
+
+# Set or override primary interface
netif=$1
+[ -e "/tmp/net.bootdev" ] && read netif < /tmp/net.bootdev
# Figure out the handler for root=dhcp by recalling all netroot cmdline
# handlers
# Load dhcp options
[ -e /tmp/dhclient.$netif.dhcpopts ] && . /tmp/dhclient.$netif.dhcpopts
+ # If we have a specific bootdev with no dhcpoptions or empty root-path,
+ # we die. Otherwise we just warn
+ if [ -z "$new_root_path" ] ; then
+ [ -n "$BOOTDEV" ] && die "No dhcp root-path received for '$BOOTDEV'"
+ warn "No dhcp root-path received for '$BOOTDEV' trying other interfaces if available"
+ exit 1
+ fi
+
# Set netroot to new_root_path, so cmdline parsers don't call
netroot=$new_root_path
fi
# We're here, so we can assume that upping interfaces is now ok
-. /tmp/net.$netif.up
+[ -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
# XXX other variables to export?
if $handler $netif $netroot $NEWROOT; then
# Network rootfs mount successful
- [ -f /tmp/dhclient.$netif.lease ] && cp /tmp/dhclient.$netif.lease /tmp/net.$netif.lease
- [ -f /tmp/dhclient.$netif.dhcpopts ] && cp /tmp/dhclient.$netif.dhcpopts /tmp/net.$netif.dhcpopts
+ for iface in $IFACES ; do
+ [ -f /tmp/dhclient.$iface.lease ] && cp /tmp/dhclient.$iface.lease /tmp/net.$iface.lease
+ [ -f /tmp/dhclient.$iface.dhcpopts ] && cp /tmp/dhclient.$iface.dhcpopts /tmp/net.$iface.dhcpopts
+ done
# Save used netif for later use
- echo $netif > /tmp/net.bootdev
+ [ ! -f /tmp/net.ifaces ] && echo $netif > /tmp/net.ifaces
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
+ if [ -z "$BOOTDEV" ] ; then
+ ip link set $netif down
+ ip addr flush dev $netif
+ echo "#empty" > /etc/resolv.conf
+ fi
fi
exit 0
#
# ip=<client-IP-number>:<server-id>:<gateway-IP-number>:<netmask>:<client-hostname>:<interface>:[dhcp|on|any|none|off]
#
+# When supplying more than only ip= line, <interface> is mandatory and
+# bootdev= must contain the name of the primary interface to use for
+# routing,dns,dhcp-options,etc.
+#
# Sadly there's no easy way to split ':' separated lines into variables
ip_to_var() {
return;
fi
+# Count ip= lines to decide whether we need bootdev= or not
+if [ -z "$NEEDBOOTDEV" ] ; then
+ [ "$CMDLINE" ] || read CMDLINE < /proc/cmdline
+ local count=0
+ for p in $CMDLINE; do
+ [ "${p%%=*}" = "ip" ] && count=$(( $count + 1 ))
+ done
+ [ $count -gt 1 ] && NEEDBOOTDEV=1
+fi
+
+# If needed, check if bootdev= contains anything usable
+if [ -n "$NEEDBOOTDEV" ] ; then
+ BOOTDEV=$(getarg bootdev=) || die "Please supply bootdev argument for multiple ip= lines"
+ [ -z "$BOOTDEV" ] && die "Bootdev argument is empty"
+fi
+
# Check ip= lines
# XXX Would be nice if we could errorcheck ip addresses here as well
[ "$CMDLINE" ] || read CMDLINE < /proc/cmdline
ip_to_var ${p#ip=}
+ # We need to have an ip= line for the specified bootdev
+ [ -n "$NEEDBOOTDEV" ] && [ "$dev" = "$BOOTDEV" ] && BOOTDEVOK=1
+
# Empty autoconf defaults to 'dhcp'
if [ -z "$autoconf" ] ; then
warn "Empty autoconf values default to dhcp"
die "Sorry, automatic calculation of netmask is not yet supported"
;;
dhcp|on|any) \
+ [ -n "$NEEDBOOTDEV" ] && [ -z "$dev" ] && \
+ die "Sorry, '$p' does not make sense for multiple interface configurations"
[ -n "$ip" ] && \
die "For argument '$p'\nSorry, setting client-ip does not make sense for '$autoconf'"
;;
*) die "For argument '$p'\nSorry, unknown value '$autoconf'";;
esac
- # We don't like duplicate device configs
if [ -n "$dev" ] ; then
+ # We don't like duplicate device configs
if [ -n "$IFACES" ] ; then
for i in $IFACES ; do
[ "$dev" = "$i" ] && die "For argument '$p'\nDuplication configurations for '$dev'"
done
fi
+ # IFACES list for later use
IFACES="$IFACES $dev"
fi
- # Do we need DHCP? (It's simpler to check for a set ip. Checks above ensure that if
- # ip is there, we're static)
- [ -n "$NEEDDHCP" ] && [ -z "$ip" ] && DHCPOK="1"
-
- # Do we need srv OR dhcp?
- if [ -n "$DHCPORSERVER" ] ; then
- [ -n "$DHCPOK" ] && SRVOK="1"
- [ -n "$srv" ] && SRVOK="1"
+ # Small optimization for udev rules
+ [ -z "$NEEDBOOTDEV" ] && [ -n "$dev" ] && BOOTDEV=$dev
+
+ # Do we need to check for specific options?
+ if [ -n "$NEEDDHCP" ] || [ -n "$DHCPORSERVER" ] ; then
+ # Correct device? (Empty is ok as well)
+ [ "$dev" = "$BOOTDEV" ] || continue
+ # Server-ip is there?
+ [ -n "$DHCPORSERVER" ] && [ -n "$srv" ] && continue
+ # dhcp? (It's simpler to check for a set ip. Checks above ensure that if
+ # ip is there, we're static
+ [ -z "$ip" ] && continue
+ # Not good!
+ die "Server-ip or dhcp for netboot needed, but current arguments say otherwise"
fi
done
-[ -n "$NEEDDHCP" ] && [ -z "$DHCPOK" ] && die "Server-ip or dhcp for netboot needed, but current arguments say otherwise"
+# This ensures that BOOTDEV is always first in IFACES
+if [ -n "$BOOTDEV" ] && [ -n "$IFACES" ] ; then
+ IFACES="${IFACES%$BOOTDEV*} ${IFACES#*$BOOTDEV}"
+ IFACES="$BOOTDEV $IFACES"
+fi
+
+# Store BOOTDEV and IFACES for later use
+[ -n "$BOOTDEV" ] && echo $BOOTDEV > /tmp/net.bootdev
+[ -n "$IFACES" ] && echo $IFACES > /tmp/net.ifaces
-[ -n "$DHCPORSERVER" ] && [ -z "$SRVOK" ] && die "Server-ip or dhcp for netboot needed, but current arguments say otherwise"
+# We need a ip= line for the configured bootdev=
+[ -n "$NEEDBOOTDEV" ] && [ -z "$BOOTDEVOK" ] && die "Bootdev Argument '$BOOTDEV' not found"
\ No newline at end of file
#!/bin/sh
# Don't write anything if we don't know our bootdev
-[ -f /tmp/net.bootdev ] || return 1
+[ -f /tmp/net.ifaces ] || return 1
-read netif < /tmp/net.bootdev
+read IFACES < /tmp/net.ifaces
-cat /sys/class/net/$netif/address > /tmp/net.$netif.hwaddr
-echo "# Generated by dracut initrd" > /tmp/net.$netif.ifcfg
-echo "DEVICE=$netif" >> /tmp/net.$netif.ifcfg
-echo "HWADDR=$(cat /sys/class/net/$netif/address)" >> /tmp/net.$netif.ifcfg
-echo "TYPE=Ethernet" >> /tmp/net.$netif.ifcfg
-echo "ONBOOT=yes" >> /tmp/net.$netif.ifcfg
-if [ -f /tmp/net.$netif.lease ]; then
- echo "BOOTPROTO=dhcp" >> /tmp/net.$netif.ifcfg
-else
- echo "BOOTPROTO=none" >> /tmp/net.$netif.ifcfg
- # If we've booted with static ip= lines, the override file is there
- . /tmp/net.$netif.override
- echo "IPADDR=$ip" >> /tmp/net.$netif.ifcfg
- echo "NETMASK=$mask" >> /tmp/net.$netif.ifcfg
- [ -n "$gw" ] && echo "GATEWAY=$gw" >> /tmp/net.$netif.ifcfg
-fi
+for netif in $IFACES ; do
+ cat /sys/class/net/$netif/address > /tmp/net.$netif.hwaddr
+ echo "# Generated by dracut initrd" > /tmp/net.$netif.ifcfg
+ echo "DEVICE=$netif" >> /tmp/net.$netif.ifcfg
+ echo "HWADDR=$(cat /sys/class/net/$netif/address)" >> /tmp/net.$netif.ifcfg
+ echo "TYPE=Ethernet" >> /tmp/net.$netif.ifcfg
+ echo "ONBOOT=yes" >> /tmp/net.$netif.ifcfg
+ if [ -f /tmp/net.$netif.lease ]; then
+ echo "BOOTPROTO=dhcp" >> /tmp/net.$netif.ifcfg
+ else
+ echo "BOOTPROTO=none" >> /tmp/net.$netif.ifcfg
+ # If we've booted with static ip= lines, the override file is there
+ . /tmp/net.$netif.override
+ echo "IPADDR=$ip" >> /tmp/net.$netif.ifcfg
+ echo "NETMASK=$mask" >> /tmp/net.$netif.ifcfg
+ [ -n "$gw" ] && echo "GATEWAY=$gw" >> /tmp/net.$netif.ifcfg
+ fi
+done