|
|
1bf31c |
From f9883b51b1fafd30a91e9efda3260067a8f87ea5 Mon Sep 17 00:00:00 2001
|
|
|
1bf31c |
From: Enzo Matsumiya <ematsumiya@suse.de>
|
|
|
1bf31c |
Date: Mon, 3 Aug 2020 11:21:36 -0300
|
|
|
1bf31c |
Subject: [PATCH] 95nvmf: add NVMe over TCP support
|
|
|
1bf31c |
|
|
|
1bf31c |
Add support to boot from an NVMe over TCP device.
|
|
|
1bf31c |
|
|
|
1bf31c |
Example of supported command line formats:
|
|
|
1bf31c |
|
|
|
1bf31c |
nvme.discover=tcp:192.168.1.3::4420
|
|
|
1bf31c |
nvme.discover=tcp:192.168.1.3 # will use 4420 as default svcid
|
|
|
1bf31c |
|
|
|
1bf31c |
- Create is_nvmf() function to handle all fabrics types
|
|
|
1bf31c |
- Fix parse_nvmf_discover() to correctly use the default values
|
|
|
1bf31c |
- Auxiliary function to validate an IP connection
|
|
|
1bf31c |
- Fix inverted result for getargbool when reading "rd.nonvmf" command line parameter
|
|
|
1bf31c |
|
|
|
1bf31c |
Requires rd.neednet=1
|
|
|
1bf31c |
Requires adding/replacing STARTMODE in /etc/sysconfig/network/ifcfg-ethX to "nfsroot"
|
|
|
1bf31c |
to avoid shutdown hanging in initiator
|
|
|
1bf31c |
|
|
|
1bf31c |
Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de>
|
|
|
1bf31c |
(cherry picked from commit 019610af266bcaef711715266bc0ca4be1044150)
|
|
|
1bf31c |
|
|
|
1bf31c |
Resolves: #1885417
|
|
|
1bf31c |
---
|
|
|
1bf31c |
modules.d/95nvmf/module-setup.sh | 25 ++++---
|
|
|
1bf31c |
modules.d/95nvmf/parse-nvmf-boot-connections.sh | 97 ++++++++++++++++++-------
|
|
|
1bf31c |
2 files changed, 84 insertions(+), 38 deletions(-)
|
|
|
1bf31c |
|
|
|
1bf31c |
diff --git a/modules.d/95nvmf/module-setup.sh b/modules.d/95nvmf/module-setup.sh
|
|
|
1bf31c |
index db43ec01..418b5e0c 100755
|
|
|
1bf31c |
--- a/modules.d/95nvmf/module-setup.sh
|
|
|
1bf31c |
+++ b/modules.d/95nvmf/module-setup.sh
|
|
|
1bf31c |
@@ -6,9 +6,9 @@ check() {
|
|
|
1bf31c |
[ -f /etc/nvme/hostnqn ] || return 255
|
|
|
1bf31c |
[ -f /etc/nvme/hostid ] || return 255
|
|
|
1bf31c |
|
|
|
1bf31c |
- is_nvme_fc() {
|
|
|
1bf31c |
+ is_nvmf() {
|
|
|
1bf31c |
local _dev=$1
|
|
|
1bf31c |
- local traddr
|
|
|
1bf31c |
+ local trtype
|
|
|
1bf31c |
|
|
|
1bf31c |
[[ -L "/sys/dev/block/$_dev" ]] || return 0
|
|
|
1bf31c |
cd -P "/sys/dev/block/$_dev" || return 0
|
|
|
1bf31c |
@@ -18,19 +18,19 @@ check() {
|
|
|
1bf31c |
for d in device/nvme* ; do
|
|
|
1bf31c |
[ -L "$d" ] || continue
|
|
|
1bf31c |
if readlink "$d" | grep -q nvme-fabrics ; then
|
|
|
1bf31c |
- traddr=$(cat "$d"/address)
|
|
|
1bf31c |
- break
|
|
|
1bf31c |
- fi
|
|
|
1bf31c |
- done
|
|
|
1bf31c |
- [[ "${traddr#traddr=nn-}" != "$traddr" ]]
|
|
|
1bf31c |
+ trtype=$(cat "$d"/transport)
|
|
|
1bf31c |
+ break
|
|
|
1bf31c |
+ fi
|
|
|
1bf31c |
+ done
|
|
|
1bf31c |
+ [[ "$trtype" == "fc" ]] || [[ "$trtype" == "tcp" ]] || [[ "$trtype" == "rdma" ]]
|
|
|
1bf31c |
}
|
|
|
1bf31c |
|
|
|
1bf31c |
[[ $hostonly ]] || [[ $mount_needs ]] && {
|
|
|
1bf31c |
pushd . >/dev/null
|
|
|
1bf31c |
- for_each_host_dev_and_slaves is_nvme_fc
|
|
|
1bf31c |
- local _is_nvme_fc=$?
|
|
|
1bf31c |
+ for_each_host_dev_and_slaves is_nvmf
|
|
|
1bf31c |
+ local _is_nvmf=$?
|
|
|
1bf31c |
popd >/dev/null
|
|
|
1bf31c |
- [[ $_is_nvme_fc == 0 ]] || return 255
|
|
|
1bf31c |
+ [[ $_is_nvmf == 0 ]] || return 255
|
|
|
1bf31c |
if [ ! -f /sys/class/fc/fc_udev_device/nvme_discovery ] ; then
|
|
|
1bf31c |
if [ ! -f /etc/nvme/discovery.conf ] ; then
|
|
|
1bf31c |
echo "No discovery arguments present"
|
|
|
1bf31c |
@@ -43,13 +43,14 @@ check() {
|
|
|
1bf31c |
|
|
|
1bf31c |
# called by dracut
|
|
|
1bf31c |
depends() {
|
|
|
1bf31c |
- echo bash rootfs-block
|
|
|
1bf31c |
+ echo bash rootfs-block network
|
|
|
1bf31c |
return 0
|
|
|
1bf31c |
}
|
|
|
1bf31c |
|
|
|
1bf31c |
# called by dracut
|
|
|
1bf31c |
installkernel() {
|
|
|
1bf31c |
instmods nvme_fc lpfc qla2xxx
|
|
|
1bf31c |
+ hostonly="" instmods nvme_tcp nvme_fabrics
|
|
|
1bf31c |
}
|
|
|
1bf31c |
|
|
|
1bf31c |
# called by dracut
|
|
|
1bf31c |
@@ -76,6 +77,8 @@ install() {
|
|
|
1bf31c |
inst_simple "/etc/nvme/hostnqn"
|
|
|
1bf31c |
inst_simple "/etc/nvme/hostid"
|
|
|
1bf31c |
|
|
|
1bf31c |
+ inst_multiple ip sed
|
|
|
1bf31c |
+
|
|
|
1bf31c |
inst_multiple nvme
|
|
|
1bf31c |
inst_multiple -o \
|
|
|
1bf31c |
"$systemdsystemunitdir/nvm*-connect@.service" \
|
|
|
1bf31c |
diff --git a/modules.d/95nvmf/parse-nvmf-boot-connections.sh b/modules.d/95nvmf/parse-nvmf-boot-connections.sh
|
|
|
1bf31c |
index 0d16b871..61c6dec1 100755
|
|
|
1bf31c |
--- a/modules.d/95nvmf/parse-nvmf-boot-connections.sh
|
|
|
1bf31c |
+++ b/modules.d/95nvmf/parse-nvmf-boot-connections.sh
|
|
|
1bf31c |
@@ -8,69 +8,102 @@
|
|
|
1bf31c |
# Examples:
|
|
|
1bf31c |
# nvmf.hostnqn=nqn.2014-08.org.nvmexpress:uuid:37303738-3034-584d-5137-333230423843
|
|
|
1bf31c |
# nvmf.discover=rdma:192.168.1.3::4420
|
|
|
1bf31c |
+# nvme.discover=tcp:192.168.1.3::4420
|
|
|
1bf31c |
+# nvme.discover=tcp:192.168.1.3
|
|
|
1bf31c |
# nvmf.discover=fc:auto
|
|
|
1bf31c |
#
|
|
|
1bf31c |
# Note: FC does autodiscovery, so typically there is no need to
|
|
|
1bf31c |
# specify any discover parameters for FC.
|
|
|
1bf31c |
#
|
|
|
1bf31c |
|
|
|
1bf31c |
+type is_ip >/dev/null 2>&1 || . /lib/net-lib.sh
|
|
|
1bf31c |
+
|
|
|
1bf31c |
+if getargbool 0 rd.nonvmf ; then
|
|
|
1bf31c |
+ warn "rd.nonvmf=0: skipping nvmf"
|
|
|
1bf31c |
+ return 0
|
|
|
1bf31c |
+fi
|
|
|
1bf31c |
+
|
|
|
1bf31c |
+initqueue --onetime modprobe --all -b -q nvme nvme_tcp nvme_core nvme_fabrics
|
|
|
1bf31c |
+
|
|
|
1bf31c |
+traddr="none"
|
|
|
1bf31c |
+trtype="none"
|
|
|
1bf31c |
+hosttraddr="none"
|
|
|
1bf31c |
+trsvcid=4420
|
|
|
1bf31c |
+
|
|
|
1bf31c |
+validate_ip_conn() {
|
|
|
1bf31c |
+ if ! getargbool 0 rd.neednet ; then
|
|
|
1bf31c |
+ warn "$trtype transport requires rd.neednet=1"
|
|
|
1bf31c |
+ return 1
|
|
|
1bf31c |
+ fi
|
|
|
1bf31c |
+
|
|
|
1bf31c |
+ local_address=$(ip -o route get to $traddr | sed -n 's/.*src \([0-9a-f.:]*\).*/\1/p')
|
|
|
1bf31c |
+
|
|
|
1bf31c |
+ # confirm we got a local IP address
|
|
|
1bf31c |
+ if ! is_ip "$local_address" ; then
|
|
|
1bf31c |
+ warn "$traddr is an invalid address";
|
|
|
1bf31c |
+ return 1
|
|
|
1bf31c |
+ fi
|
|
|
1bf31c |
+
|
|
|
1bf31c |
+ ifname=$(ip -o route get to $local_address | sed -n 's/.*dev \([^ ]*\).*/\1/p')
|
|
|
1bf31c |
+
|
|
|
1bf31c |
+ if ip l show "$ifname" >/dev/null 2>&1 ; then
|
|
|
1bf31c |
+ warn "invalid network interface $ifname"
|
|
|
1bf31c |
+ return 1
|
|
|
1bf31c |
+ fi
|
|
|
1bf31c |
+
|
|
|
1bf31c |
+ # confirm there's a route to destination
|
|
|
1bf31c |
+ if ip route get "$traddr" >/dev/null 2>&1 ; then
|
|
|
1bf31c |
+ warn "no route to $traddr"
|
|
|
1bf31c |
+ return 1
|
|
|
1bf31c |
+ fi
|
|
|
1bf31c |
+}
|
|
|
1bf31c |
+
|
|
|
1bf31c |
parse_nvmf_discover() {
|
|
|
1bf31c |
OLDIFS="$IFS"
|
|
|
1bf31c |
IFS=:
|
|
|
1bf31c |
- trtype="none"
|
|
|
1bf31c |
- traddr="none"
|
|
|
1bf31c |
- hosttraddr="none"
|
|
|
1bf31c |
- trsvcid=4420
|
|
|
1bf31c |
-
|
|
|
1bf31c |
set $1
|
|
|
1bf31c |
IFS="$OLDIFS"
|
|
|
1bf31c |
|
|
|
1bf31c |
case $# in
|
|
|
1bf31c |
2)
|
|
|
1bf31c |
- trtype=$1
|
|
|
1bf31c |
- traddr=$2
|
|
|
1bf31c |
+ [ -n "$1" ] && trtype=$1
|
|
|
1bf31c |
+ [ -n "$2" ] && traddr=$2
|
|
|
1bf31c |
;;
|
|
|
1bf31c |
3)
|
|
|
1bf31c |
- trtype=$1
|
|
|
1bf31c |
- traddr=$2
|
|
|
1bf31c |
- hosttraddr=$3
|
|
|
1bf31c |
+ [ -n "$1" ] && trtype=$1
|
|
|
1bf31c |
+ [ -n "$2" ] && traddr=$2
|
|
|
1bf31c |
+ [ -n "$3" ] && hosttraddr=$3
|
|
|
1bf31c |
;;
|
|
|
1bf31c |
4)
|
|
|
1bf31c |
- trtype=$1
|
|
|
1bf31c |
- traddr=$2
|
|
|
1bf31c |
- hosttraddr=$3
|
|
|
1bf31c |
- trsvcid=$4
|
|
|
1bf31c |
+ [ -n "$1" ] && trtype=$1
|
|
|
1bf31c |
+ [ -n "$2" ] && traddr=$2
|
|
|
1bf31c |
+ [ -n "$3" ] && hosttraddr=$3
|
|
|
1bf31c |
+ [ -n "$4" ] && trsvcid=$4
|
|
|
1bf31c |
;;
|
|
|
1bf31c |
*)
|
|
|
1bf31c |
warn "Invalid arguments for nvmf.discover=$1"
|
|
|
1bf31c |
return 1
|
|
|
1bf31c |
;;
|
|
|
1bf31c |
esac
|
|
|
1bf31c |
- if [ -z "$traddr" ] ; then
|
|
|
1bf31c |
+ if [ "$traddr" = "none" ] ; then
|
|
|
1bf31c |
warn "traddr is mandatory for $trtype"
|
|
|
1bf31c |
return 1;
|
|
|
1bf31c |
fi
|
|
|
1bf31c |
- [ -z "$hosttraddr" ] && hosttraddr="none"
|
|
|
1bf31c |
- [ -z "$trsvcid" ] && trsvcid="none"
|
|
|
1bf31c |
if [ "$trtype" = "fc" ] ; then
|
|
|
1bf31c |
- if [ -z "$hosttraddr" ] ; then
|
|
|
1bf31c |
+ if [ "$hosttraddr" = "none" ] ; then
|
|
|
1bf31c |
warn "host traddr is mandatory for fc"
|
|
|
1bf31c |
return 1
|
|
|
1bf31c |
fi
|
|
|
1bf31c |
elif [ "$trtype" != "rdma" ] && [ "$trtype" != "tcp" ] ; then
|
|
|
1bf31c |
warn "unsupported transport $trtype"
|
|
|
1bf31c |
return 1
|
|
|
1bf31c |
- elif [ -z "$trsvcid" ] ; then
|
|
|
1bf31c |
- trsvcid=4420
|
|
|
1bf31c |
+ fi
|
|
|
1bf31c |
+ if [ "$trtype" = "tcp" ]; then
|
|
|
1bf31c |
+ validate_ip_conn
|
|
|
1bf31c |
fi
|
|
|
1bf31c |
echo "--transport=$trtype --traddr=$traddr --host-traddr=$hosttraddr --trsvcid=$trsvcid" >> /etc/nvme/discovery.conf
|
|
|
1bf31c |
}
|
|
|
1bf31c |
|
|
|
1bf31c |
-if ! getargbool 0 rd.nonvmf ; then
|
|
|
1bf31c |
- info "rd.nonvmf=0: skipping nvmf"
|
|
|
1bf31c |
- return 0
|
|
|
1bf31c |
-fi
|
|
|
1bf31c |
-
|
|
|
1bf31c |
nvmf_hostnqn=$(getarg nvmf.hostnqn=)
|
|
|
1bf31c |
if [ -n "$nvmf_hostnqn" ] ; then
|
|
|
1bf31c |
echo "$nvmf_hostnqn" > /etc/nvme/hostnqn
|
|
|
1bf31c |
@@ -89,7 +122,17 @@ done
|
|
|
1bf31c |
[ -f "/etc/nvme/hostid" ] || exit 0
|
|
|
1bf31c |
|
|
|
1bf31c |
if [ -f "/etc/nvme/discovery.conf" ] ; then
|
|
|
1bf31c |
- /sbin/initqueue --onetime --unique --name nvme-discover /usr/sbin/nvme connect-all
|
|
|
1bf31c |
+ if [ "$trtype" = "tcp" ] ; then
|
|
|
1bf31c |
+ /sbin/initqueue --settled --onetime --unique --name nvme-discover /usr/sbin/nvme connect-all
|
|
|
1bf31c |
+ > /tmp/net.$ifname.did-setup
|
|
|
1bf31c |
+ else
|
|
|
1bf31c |
+ /sbin/initqueue --onetime --unique --name nvme-discover /usr/sbin/nvme connect-all
|
|
|
1bf31c |
+ fi
|
|
|
1bf31c |
else
|
|
|
1bf31c |
- /sbin/initqueue --finished --unique --name nvme-fc-autoconnect echo 1 > /sys/class/fc/fc_udev_device/nvme_discovery
|
|
|
1bf31c |
+ if [ "$trtype" = "tcp" ] ; then
|
|
|
1bf31c |
+ /sbin/initqueue --settled --onetime --unique /usr/sbin/nvme connect-all -t tcp -a $traddr -s $trsvcid
|
|
|
1bf31c |
+ > /tmp/net.$ifname.did-setup
|
|
|
1bf31c |
+ else
|
|
|
1bf31c |
+ /sbin/initqueue --finished --unique --name nvme-fc-autoconnect echo 1 > /sys/class/fc/fc_udev_device/nvme_discovery
|
|
|
1bf31c |
+ fi
|
|
|
1bf31c |
fi
|
|
|
1bf31c |
|