You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

145 lines
3.4 KiB

#!/bin/sh
type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh
PATH=/usr/sbin:/usr/bin:/sbin:/bin
# Huh? Empty $1?
[ -z "$1" ] && exit 1
# Huh? Empty $2?
[ -z "$2" ] && exit 1
# Huh? Empty $3?
[ -z "$3" ] && exit 1
# root is in the form root=nbd:srv:port[:fstype[:rootflags[:nbdopts]]]
# shellcheck disable=SC2034
netif="$1"
nroot="$2"
NEWROOT="$3"
# If it's not nbd we don't continue
[ "${nroot%%:*}" = "nbd" ] || return
nroot=${nroot#nbd:}
nbdserver=${nroot%%:*}
if [ "${nbdserver%"${nbdserver#?}"}" = "[" ]; then
nbdserver=${nroot#[}
nbdserver=${nbdserver%%]:*}
nroot=${nroot#*]:}
else
nroot=${nroot#*:}
fi
nbdport=${nroot%%:*}
nroot=${nroot#*:}
nbdfstype=${nroot%%:*}
nroot=${nroot#*:}
nbdflags=${nroot%%:*}
nbdopts=${nroot#*:}
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}
# XXX better way to wait for the device to be made?
i=0
while [ ! -b /dev/nbd0 ]; do
[ $i -ge 20 ] && exit 1
udevadm settle --exit-if-exists=/dev/nbd0
i=$((i + 1))
done
# If we didn't get a root= on the command line, then we need to
# add the udev rules for mounting the nbd0 device
if [ "$root" = "block:/dev/root" -o "$root" = "dhcp" ]; then
printf 'KERNEL=="nbd0", ENV{DEVTYPE}!="partition", ENV{ID_FS_TYPE}=="?*", SYMLINK+="root"\n' > /etc/udev/rules.d/99-nbd-root.rules
udevadm control --reload
wait_for_dev -n /dev/root
if [ -z "$DRACUT_SYSTEMD" ]; then
type write_fs_tab > /dev/null 2>&1 || . /lib/fs-lib.sh
write_fs_tab /dev/root "$nbdfstype" "$fsopts"
printf '/bin/mount %s\n' \
"$NEWROOT" \
> "$hookdir"/mount/01-$$-nbd.sh
else
mkdir -p /run/systemd/system/sysroot.mount.d
cat << EOF > /run/systemd/system/sysroot.mount.d/dhcp.conf
[Mount]
Where=/sysroot
What=/dev/root
Type=$nbdfstype
Options=$fsopts
EOF
systemctl --no-block daemon-reload
fi
# if we're on systemd, use the nbd-generator script
# to create the /sysroot mount.
fi
# supported since nbd 3.8 via 77e97612
if strstr "$(nbd-client --help 2>&1)" "systemd-mark"; then
preopts="-systemd-mark $preopts"
fi
if ! [ "$nbdport" -gt 0 ] 2> /dev/null; then
nbdport="-name $nbdport"
fi
if ! nbd-client -check /dev/nbd0 > /dev/null; then
# shellcheck disable=SC2086
nbd-client "$nbdserver" $nbdport /dev/nbd0 $preopts $opts || exit 1
fi
# NBD doesn't emit uevents when it gets connected, so kick it
echo change > /sys/block/nbd0/uevent
udevadm settle
need_shutdown
exit 0