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