]> git.ipfire.org Git - thirdparty/dracut.git/commitdiff
netroot: add common handler for network root devices
authorDavid Dillow <dave@thedillows.org>
Mon, 1 Jun 2009 04:42:43 +0000 (00:42 -0400)
committerDavid Dillow <dave@thedillows.org>
Mon, 1 Jun 2009 04:42:43 +0000 (00:42 -0400)
/sbin/netroot is a jumping off point to allow various network
root devices to share infrastructure. It will loop over scriptlets
in the netroot handler, looking for a handler to run for this type
of netroot. Handlers can do choose to act based on command line
options to the kernel, or via DHCP options received on this interface.
They should massage root= into a form suitable for their handler.

dracut
modules.d/40network/60-net.rules
modules.d/40network/dhcp-fallback.sh [new file with mode: 0755]
modules.d/40network/ifup
modules.d/40network/install
modules.d/40network/netroot [new file with mode: 0755]
modules.d/99base/init

diff --git a/dracut b/dracut
index 84c194ef00978d24c2f0787c9a73e6ae033a7594..e5e7ecd7ab0cc689f512e32f71e7e774bae1490a 100755 (executable)
--- a/dracut
+++ b/dracut
@@ -96,7 +96,7 @@ if [[ -f $outfile && ! $force ]]; then
     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.
index 4b030c3fe2690536260b4e1d1098a77fe0fa205d..6c795081989bef6952b5f4746c03f73f98b6665b 100644 (file)
@@ -1 +1,2 @@
 ACTION=="add", SUBSYSTEM=="net", RUN+="/sbin/ifup $env{INTERFACE}"
+ACTION=="online", SUBSYSTEM=="net", RUN+="/sbin/netroot $env{INTERFACE}"
diff --git a/modules.d/40network/dhcp-fallback.sh b/modules.d/40network/dhcp-fallback.sh
new file mode 100755 (executable)
index 0000000..1f4ec0c
--- /dev/null
@@ -0,0 +1,14 @@
+# 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
index ee4bc4aa0314013fadb1bf02ecf80aee14e508b7..981a207f958b27e1c63bb2b61e66423e8f989abd 100755 (executable)
@@ -12,8 +12,10 @@ getarg rdnetdebug && {
 
 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" ] && {
@@ -93,10 +95,8 @@ ip_to_var() {
     [ -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
index d9ec7f0453614eaf3f6a6b48cafc4ba7ec304f87..3112494218e3c53c4744530e201e68ec7c19776c 100755 (executable)
@@ -2,8 +2,10 @@
 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"
diff --git a/modules.d/40network/netroot b/modules.d/40network/netroot
new file mode 100755 (executable)
index 0000000..3d03e72
--- /dev/null
@@ -0,0 +1,52 @@
+#!/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
index 73e96fd4cb12ef9979736b7312e4373f4e25b706..b4fce6a666b79a730bf5285ae390cce99db7cdc3 100755 (executable)
@@ -47,12 +47,21 @@ fi
 
 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