[RFC PATCH 9/9] Add NBD support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This adds basic support for root on a network block device to
the netroot framework.

Signed-off-by: David Dillow <dave@xxxxxxxxxxxxxx>
---
 modules.d/95nbd/check            |   11 ++++
 modules.d/95nbd/install          |    7 +++
 modules.d/95nbd/nbd-netroot.sh   |   11 ++++
 modules.d/95nbd/nbdroot          |   96 ++++++++++++++++++++++++++++++++++++++
 modules.d/95nbd/parse-nbdroot.sh |   49 +++++++++++++++++++
 5 files changed, 174 insertions(+), 0 deletions(-)
 create mode 100755 modules.d/95nbd/check
 create mode 100755 modules.d/95nbd/install
 create mode 100755 modules.d/95nbd/nbd-netroot.sh
 create mode 100755 modules.d/95nbd/nbdroot
 create mode 100755 modules.d/95nbd/parse-nbdroot.sh

diff --git a/modules.d/95nbd/check b/modules.d/95nbd/check
new file mode 100755
index 0000000..f94d63b
--- /dev/null
+++ b/modules.d/95nbd/check
@@ -0,0 +1,11 @@
+#!/bin/sh
+# We depend on network modules being loaded
+[ "$1" = "-d" ] && echo network
+
+# If hostonly was requested, fail the check if we are not actually
+# booting from root.
+[ "$1" = "-h" ] && ! egrep -q '/ /dev/nbd[0-9]*' /proc/mounts && exit 1
+
+# If our prerequisites are not met, fail anyways.
+which nbd-client >/dev/null 2>&1 || exit 1
+exit 0
diff --git a/modules.d/95nbd/install b/modules.d/95nbd/install
new file mode 100755
index 0000000..3a80da1
--- /dev/null
+++ b/modules.d/95nbd/install
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+inst nbd-client
+inst_hook cmdline 90 "$moddir/parse-nbdroot.sh"
+inst_hook netroot 90 "$moddir/nbd-netroot.sh"
+inst "$moddir/nbdroot" "/sbin/nbdroot"
+instmods nbd
diff --git a/modules.d/95nbd/nbd-netroot.sh b/modules.d/95nbd/nbd-netroot.sh
new file mode 100755
index 0000000..74b3da8
--- /dev/null
+++ b/modules.d/95nbd/nbd-netroot.sh
@@ -0,0 +1,11 @@
+#!/bin/sh # for highlighting
+
+if [ "$root" = "dhcp" ]; then
+    if [ -n "$new_root_path" -a -z "${new_root_path%%nbd:*}" ]; then
+	root="$new_root_path"
+    fi
+fi
+
+if [ -z "${root%nbd:*}" ]; then
+    handler=/sbin/nbdroot
+fi
diff --git a/modules.d/95nbd/nbdroot b/modules.d/95nbd/nbdroot
new file mode 100755
index 0000000..51120c2
--- /dev/null
+++ b/modules.d/95nbd/nbdroot
@@ -0,0 +1,96 @@
+#!/bin/sh
+
+. /lib/dracut-lib
+
+PATH=$PATH:/sbin:/usr/sbin
+
+# XXX needs error handling like ifup/dhclient-script
+
+if getarg rdnetdebug; then
+    exec > /tmp/nbdroot.$1.$$.out
+    exec 2>> /tmp/nbdroot.$1.$$.out
+    set -x
+fi
+
+# root is in the form root=nbd:server:port:fstype:fsopts:nbdopts
+netif="$1"
+root="$2"
+
+root=${root#nbd:}
+nbdserver=${root%%:*}; root=${root#*:}
+nbdport=${root%%:*}; root=${root#*:}
+nbdfstype=${root%%:*}; root=${root#*:}
+nbdflags=${root%%:*}
+nbdopts=${root#*:}
+
+if [ "$nbdopts" = "$nbdflags" ]; then
+    unset nbdopts
+fi
+if [ "$nbdflags" = "$nbdfstype" ]; then
+    unset nbdflags
+fi
+if [ "$nbdfstype" = "$nbdport" ]; then
+    unset nbdfstype
+fi
+if [ -z "$nbdfstype" ]; then
+    nbdfstype=auto
+fi
+
+# look through the NBD options and pull out the ones that need to
+# go before the host etc. Append a ',' so we know we terminate the loop
+nbdopts=${nbdopts},
+while [ -n "$nbdopts" ]; do
+    f=${nbdopts%%,*}
+    nbdopts=${nbdopts#*,}
+    if [ -z "$f" ]; then
+        break
+    fi
+    if [ -z "${f%bs=*}" -o -z "${f%timeout=*}" ]; then
+        preopts="$preopts $f"
+        continue
+    fi
+    opts="$opts $f"
+done
+
+# look through the flags and see if any are overridden by the command line
+nbdflags=${nbdflags},
+while [ -n "$nbdflags" ]; do
+    f=${nbdflags%%,*}
+    nbdflags=${nbdflags#*,}
+    if [ -z "$f" ]; then
+        break
+    fi
+    if [ "$f" = "ro" -o "$f" = "rw" ]; then
+        nbdrw=$f
+        continue
+    fi
+    fsopts=${fsopts+$fsopts,}$f
+done
+
+getarg ro && nbdrw=ro
+getarg rw && nbdrw=rw
+fsopts=${fsopts+$fsopts,}${nbdrw}
+
+modprobe nbd || exit 1
+
+# XXX better way to wait for the device to be made?
+i=0
+while [ ! -b /dev/nbd0 ]; do
+    [ $i -ge 20 ] && exit 1
+    sleep 0.1
+    i=$(( $i + 1))
+done
+
+# XXX netroot expects to have the handler mount things, but we should
+# XXX allow LVM, LUKS, etc over nbd
+
+nbd-client $preopts "$nbdserver" "$nbdport" /dev/nbd0 $opts || exit 1
+
+if ! mount -t $nbdfstype -o$fsopts /dev/nbd0 $NEWROOT; then
+    # Mount failed, clean up after ourselves so if we try a different
+    # interface it can succeed
+    nbd-client -d /dev/nbd0
+    exit 1
+fi
+
+exit 0
diff --git a/modules.d/95nbd/parse-nbdroot.sh b/modules.d/95nbd/parse-nbdroot.sh
new file mode 100755
index 0000000..4bedaab
--- /dev/null
+++ b/modules.d/95nbd/parse-nbdroot.sh
@@ -0,0 +1,49 @@
+#!/bin/dash
+
+# It'd be nice if this could share rules with 99-block.sh, but since
+# the kernel side adds nbd{1..16} when the module is loaded -- before
+# they are associated with a server -- we cannot use the udev add rule
+# to find it
+#
+# XXX actually we could, if we move to root=XXX and netroot=XXX, then
+# you could do root=LABEL=/ nbdroot=XXX, or netroot=nbd:XXX
+#
+# However, we need to be 90-nbd.sh to catch root=/dev/nbd*
+#
+# Preferred format:
+#	root=nbd:srv:port[:fstype[:rootflags[:nbdopts]]]
+#
+# nbdopts is a comma seperated list of options to give to nbd-client
+#
+#
+# Legacy formats:
+#	nbdroot=srv,port
+#	nbdroot=srv:port[:fstype[:rootflags[:nbdopts]]]
+#	root=dhcp nbdroot=srv:port[:fstype[:rootflags[:nbdopts]]]
+#	root=nbd nbdroot=srv:port[:fstype[:rootflags[:nbdopts]]]
+#
+
+case "$root" in
+    nbd|dhcp|'')
+	if getarg nbdroot= > /dev/null; then
+	    root=nbd:$(getarg nbdroot=)
+	fi
+	;;
+esac
+
+# Convert the Debian style to our syntax, but avoid matches on fs arguments
+case "$root" in
+    nbd:*,*)
+	if check_occurances "$root" ',' 1 && check_occurances "$root" ':' 1;
+	then
+	    root=${root%*,}:${root#*,}
+	fi
+	;;
+esac
+
+if [ "${root%%:*}" = "nbd" ]; then
+    # XXX validate options here?
+    # XXX generate udev rules?
+    rootok=1
+    netroot=nbd
+fi
-- 
1.6.0.6

--
To unsubscribe from this list: send the line "unsubscribe initramfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux