exit 1
fi
-hookdirs="cmdline pre-udev pre-mount pre-pivot mount emergency"
+hookdirs="cmdline pre-udev netroot pre-mount pre-pivot mount emergency"
readonly initdir=$(mktemp -d -t initramfs.XXXXXX)
trap 'rm -rf "$initdir"' 0 # clean up after ourselves no matter how we die.
ACTION=="add", SUBSYSTEM=="net", RUN+="/sbin/ifup $env{INTERFACE}"
+ACTION=="online", SUBSYSTEM=="net", RUN+="/sbin/netroot $env{INTERFACE}"
--- /dev/null
+# We should go last, and default the root if needed
+
+if [ -z "$root" ]; then
+ root=dhcp
+fi
+
+if [ "$root" = "dhcp" -a -z "$netroot" ]; then
+ rootok=1
+ netroot=dhcp
+fi
+
+if [ "${netroot+set}" = "set" ]; then
+ eval "echo netroot='$netroot'" > /tmp/netroot.info
+fi
netif=$1
-# bail immediatly if the interface is already up
+# bail immediately if the interface is already up
+# or we don't need the network
[ -f "/tmp/net.$netif.up" ] && exit 0
+[ ! -f /tmp/netroot.info ] && exit 0
# loopback is always handled the same way
[ "$netif" = "lo" ] && {
[ -n "$autoconf" ] || autoconf=off
}
-root=$(getarg root)
ip=$(getarg ip)
-
-if [ "$root" = "dhcp" -a -z "$ip" ]; then
+if [ -z "$ip" ]; then
do_dhcp;
else
# spin through the kernel command line, looking for ip= lines
dracut_install ip dhclient hostname
instmods =net
inst "$moddir/ifup" "/sbin/ifup"
+inst "$moddir/netroot" "/sbin/netroot"
inst "$moddir/dhclient-script" "/sbin/dhclient-script"
instmods =networking ecb arc4
inst_rules "$moddir/60-net.rules"
+inst_hook cmdline 99 "$moddir/dhcp-fallback.sh"
inst_hook pre-pivot 10 "$moddir/kill-dhclient.sh"
mkdir -p "${initdir}/var/run"
--- /dev/null
+#!/bin/sh
+
+. /lib/dracut-lib
+
+getarg rdnetdebug && {
+ exec >/tmp/netroot.$1.$$.out
+ exec 2>>/tmp/netroot.$1.$$.out
+ set -x
+}
+
+# Only try to configure from one network interface at a time
+#
+[ "$NETROOT_LOCKED" ] || {
+ NETROOT_LOCKED=true
+ export NETROOT_LOCKED
+ exec flock -xo /tmp/netroot.lock -c "$0 $*"
+ exit 1
+}
+
+netif=$1
+
+# If we've already found a root, or we don't have the info we need,
+# then no point in looking further
+#
+[ -e /tmp/netroot.done ] && exit 0
+[ -s /tmp/netroot.info -a -s /tmp/root.info ] || exit 0
+
+# Pick up our config from the command line; we may already know the
+# handler to run
+#
+. /tmp/root.info
+. /tmp/netroot.info
+[ -e /tmp/net.$netif.dhcpopts ] && . /tmp/net.$netif.dhcpopts
+
+# Now, let the installed network root handlers figure this out
+#
+source_all netroot
+
+# If we didn't get a handler set, then we're done
+#
+if [ -z "$handler" ]; then
+ # XXX informative error message?
+ exit 0
+fi
+
+# Run the handler; don't store the root, it may change from device to device
+# XXX other variables to export?
+export NEWROOT
+if $handler $netif $root; then
+ >/tmp/netroot.done
+fi
+exit 0
if [ -z "${root%%error:*}" ]; then
case "${root%%:*}" in
- '') echo "FATAL: no root= option specified" ;;
+ '') echo "FATAL: no root= option specified, and no network support" ;;
error) echo "FATAL: ${root#error:}" ;;
esac
emergency_shell
fi
+# Network root scripts may need updated root= options,
+# so deposit them where they can see them (udev purges the env)
+{
+ echo "root='$root'"
+ echo "rflags='$rflags'"
+ echo "fstype='$fstype'"
+ echo "NEWROOT='$NEWROOT'"
+} > /tmp/root.info
+
# pre-udev scripts run before udev starts, and are run only once.
getarg 'rdbreak=pre-udev' && emergency_shell
source_all pre-udev