Browse Source

Add NBD support

This adds basic support for root on a network block device to
the netroot framework.
master
David Dillow 16 years ago
parent
commit
2b117123ec
  1. 11
      modules.d/95nbd/check
  2. 7
      modules.d/95nbd/install
  3. 11
      modules.d/95nbd/nbd-netroot.sh
  4. 96
      modules.d/95nbd/nbdroot
  5. 49
      modules.d/95nbd/parse-nbdroot.sh

11
modules.d/95nbd/check

@ -0,0 +1,11 @@ @@ -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

7
modules.d/95nbd/install

@ -0,0 +1,7 @@ @@ -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

11
modules.d/95nbd/nbd-netroot.sh

@ -0,0 +1,11 @@ @@ -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

96
modules.d/95nbd/nbdroot

@ -0,0 +1,96 @@ @@ -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

49
modules.d/95nbd/parse-nbdroot.sh

@ -0,0 +1,49 @@ @@ -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
Loading…
Cancel
Save