Blob Blame History Raw
From 8c3e65d1cecc6e3ba634efdabe5f00b38ac606d8 Mon Sep 17 00:00:00 2001
From: Harald Hoyer <harald@hoyer.xyz>
Date: Tue, 19 Dec 2017 15:43:13 +0100
Subject: [PATCH] Merge pull request #318 from danimo/fcoe-fixes

All FCOE-related SUSE patches, rebased on top of master
---
 dracut.cmdline.7.asc              |  8 ++--
 modules.d/95fcoe/fcoe-genrules.sh |  6 ++-
 modules.d/95fcoe/fcoe-up.sh       | 43 ++++++++++++++--------
 modules.d/95fcoe/module-setup.sh  | 77 +++++++++++++++++++++++----------------
 modules.d/95fcoe/parse-fcoe.sh    | 22 +++++++++--
 modules.d/95fcoe/stop-fcoe.sh     |  6 +++
 6 files changed, 105 insertions(+), 57 deletions(-)

diff --git a/dracut.cmdline.7.asc b/dracut.cmdline.7.asc
index 63c6c10f..b5f6f0f6 100644
--- a/dracut.cmdline.7.asc
+++ b/dracut.cmdline.7.asc
@@ -755,10 +755,12 @@ iscsistart -b --param node.session.timeo.replacement_timeout=30
 
 FCoE
 ~~~~
-**fcoe=**__<edd|interface|MAC>__:__{dcb|nodcb}__::
+**fcoe=**__<edd|interface|MAC>__:__{dcb|nodcb}__:__{fabric|vn2vn}__::
     Try to connect to a FCoE SAN through the NIC specified by _<interface>_ or
-    _<MAC>_ or EDD settings. For the second argument, currently only nodcb is
-    supported. This parameter can be specified multiple times.
+    _<MAC>_ or EDD settings. The second argument specifies if DCB
+    should be used. The optional third argument specifies whether
+    fabric or VN2VN mode should be used.
+    This parameter can be specified multiple times.
 +
 NOTE: letters in the MAC-address must be lowercase!
 
diff --git a/modules.d/95fcoe/fcoe-genrules.sh b/modules.d/95fcoe/fcoe-genrules.sh
index eb58601b..445a09c2 100755
--- a/modules.d/95fcoe/fcoe-genrules.sh
+++ b/modules.d/95fcoe/fcoe-genrules.sh
@@ -7,8 +7,10 @@
 # Write udev rules
 {
     if [ -n "$fcoe_mac" ] ; then
-        printf 'ACTION=="add", SUBSYSTEM=="net", ATTR{address}=="%s", RUN+="/sbin/initqueue --onetime --unique --name fcoe-up-$env{INTERFACE} /sbin/fcoe-up $env{INTERFACE} %s"\n' "$fcoe_mac" "$fcoe_dcb"
+        printf 'ACTION=="add", SUBSYSTEM=="net", ATTR{address}=="%s", RUN+="/sbin/initqueue --onetime --unique --name fcoe-up-$env{INTERFACE} /sbin/fcoe-up $env{INTERFACE} %s %s"\n' "$fcoe_mac" "$fcoe_dcb" "$fcoe_mode"
+        printf 'ACTION=="add", SUBSYSTEM=="net", ATTR{address}=="%s", RUN+="/sbin/initqueue --onetime --timeout --unique --name fcoe-timeout-$env{INTERFACE} /sbin/fcoe-up $env{INTERFACE} %s %s"\n' "$fcoe_mac" "$fcoe_dcb" "$fcoe_mode"
     else
-        printf 'ACTION=="add", SUBSYSTEM=="net", NAME=="%s", RUN+="/sbin/initqueue --onetime --unique --name fcoe-up-$env{INTERFACE} /sbin/fcoe-up $env{INTERFACE} %s"\n' "$fcoe_interface" "$fcoe_dcb"
+        printf 'ACTION=="add", SUBSYSTEM=="net", NAME=="%s", RUN+="/sbin/initqueue --onetime --unique --name fcoe-up-$env{INTERFACE} /sbin/fcoe-up $env{INTERFACE} %s %s"\n' "$fcoe_interface" "$fcoe_dcb" "$fcoe_mode"
+        printf 'ACTION=="add", SUBSYSTEM=="net", NAME=="%s", RUN+="/sbin/initqueue --onetime --timeout --unique --name fcoe-timeout-$env{INTERFACE} /sbin/fcoe-up $env{INTERFACE} %s %s"\n' "$fcoe_interface" "$fcoe_dcb" "$fcoe_mode"
     fi
 } >> /etc/udev/rules.d/92-fcoe.rules
diff --git a/modules.d/95fcoe/fcoe-up.sh b/modules.d/95fcoe/fcoe-up.sh
index ddc87b1c..570cd848 100755
--- a/modules.d/95fcoe/fcoe-up.sh
+++ b/modules.d/95fcoe/fcoe-up.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 #
 # We get called like this:
-# fcoe-up <network-device> <dcb|nodcb>
+# fcoe-up <network-device> <dcb|nodcb> <fabric|vn2vn>
 #
 # Note currently only nodcb is supported, the dcb option is reserved for
 # future use.
@@ -15,6 +15,7 @@ type ip_to_var >/dev/null 2>&1 || . /lib/net-lib.sh
 
 netif=$1
 dcb=$2
+mode=$3
 vlan="yes"
 
 iflink=$(cat /sys/class/net/$netif/iflink)
@@ -27,10 +28,18 @@ fi
 ip link set dev $netif up
 linkup "$netif"
 
+# Some fcoemon implementations expect --syslog=true
+syslogopt="--syslog"
+if fcoemon -h|grep syslog|grep -q yes; then
+    fcoemonyes="$syslogopt=yes"
+fi
+
+
 netdriver=$(readlink -f /sys/class/net/$netif/device/driver)
 netdriver=${netdriver##*/}
 
 write_fcoemon_cfg() {
+    [ -f /etc/fcoe/cfg-$netif ] && return
     echo FCOE_ENABLE=\"yes\" > /etc/fcoe/cfg-$netif
     if [ "$dcb" = "dcb" ]; then
         echo DCB_REQUIRED=\"yes\" >> /etc/fcoe/cfg-$netif
@@ -42,9 +51,23 @@ write_fcoemon_cfg() {
     else
 	    echo AUTO_VLAN=\"no\" >> /etc/fcoe/cfg-$netif
     fi
-    echo MODE=\"fabric\" >> /etc/fcoe/cfg-$netif
+    if [ "$mode" = "vn2vn" ] ; then
+        echo MODE=\"vn2vn\" >> /etc/fcoe/cfg-$netif
+    else
+        echo MODE=\"fabric\" >> /etc/fcoe/cfg-$netif
+    fi
 }
 
+if [ "$netdriver" = "bnx2x" ]; then
+    # If driver is bnx2x, do not use /sys/module/fcoe/parameters/create but fipvlan
+    modprobe 8021q
+    udevadm settle --timeout=30
+    # Sleep for 13 s to allow dcb negotiation
+    sleep 13
+    fipvlan "$netif" -c -s
+    need_shutdown
+    exit
+fi
 if [ "$dcb" = "dcb" ]; then
     # wait for lldpad to be ready
     i=0
@@ -77,20 +100,8 @@ if [ "$dcb" = "dcb" ]; then
     done
 
     sleep 1
-
-    write_fcoemon_cfg
-    fcoemon --syslog
-elif [ "$netdriver" = "bnx2x" ]; then
-    # If driver is bnx2x, do not use /sys/module/fcoe/parameters/create but fipvlan
-    modprobe 8021q
-    udevadm settle --timeout=30
-    # Sleep for 13 s to allow dcb negotiation
-    sleep 13
-    fipvlan "$netif" -c -s
-else
-    vlan="no"
-    write_fcoemon_cfg
-    fcoemon --syslog
 fi
+write_fcoemon_cfg
+fcoemon $syslogopt
 
 need_shutdown
diff --git a/modules.d/95fcoe/module-setup.sh b/modules.d/95fcoe/module-setup.sh
index eabb21c7..63f45b52 100755
--- a/modules.d/95fcoe/module-setup.sh
+++ b/modules.d/95fcoe/module-setup.sh
@@ -41,42 +41,52 @@ get_vlan_parent() {
 
 # called by dracut
 cmdline() {
-
-    for c in /sys/bus/fcoe/devices/ctlr_* ; do
-        [ -L $c ] || continue
-        read enabled < $c/enabled
-        [ $enabled -eq 0 ] && continue
-        d=$(cd -P $c; echo $PWD)
-        i=${d%/*}
-        read mac < ${i}/address
-        s=$(dcbtool gc ${i##*/} dcb | sed -n 's/^DCB State:\t*\(.*\)/\1/p')
-        if [ -z "$s" ] ; then
-            p=$(get_vlan_parent ${i})
-            if [ "$p" ] ; then
-                s=$(dcbtool gc ${p} dcb | sed -n 's/^DCB State:\t*\(.*\)/\1/p')
+    {
+        for c in /sys/bus/fcoe/devices/ctlr_* ; do
+            [ -L $c ] || continue
+            read enabled < $c/enabled
+            read mode < $c/mode
+            [ $enabled -eq 0 ] && continue
+            if [ $mode = "VN2VN" ] ; then
+                mode="vn2vn"
+            else
+                mode="fabric"
+            fi
+            d=$(cd -P $c; echo $PWD)
+            i=${d%/*}
+            ifname=${i##*/}
+            read mac < ${i}/address
+            s=$(dcbtool gc ${i##*/} dcb 2>/dev/null | sed -n 's/^DCB State:\t*\(.*\)/\1/p')
+            if [ -z "$s" ] ; then
+	        p=$(get_vlan_parent ${i})
+	        if [ "$p" ] ; then
+	            s=$(dcbtool gc ${p} dcb 2>/dev/null | sed -n 's/^DCB State:\t*\(.*\)/\1/p')
+                    ifname=${p##*/}
+	        fi
+            fi
+            if [ "$s" = "on" ] ; then
+	        dcb="dcb"
+            else
+	        dcb="nodcb"
             fi
-        fi
-        if [ "$s" = "on" ] ; then
-            dcb="dcb"
-        else
-            dcb="nodcb"
-        fi
 
-        # Some Combined Network Adapters(CNAs) implement DCB in firmware.
-        # Do not run software-based DCB or LLDP on CNAs that implement DCB.
-        # If the network interface provides hardware DCB/DCBX capabilities,
-        # DCB_REQUIRED in "/etc/fcoe/cfg-xxx" is expected to set to "no".
-        #
-        # Force "nodcb" if there's any DCB_REQUIRED="no"(child or vlan parent).
-        grep -q "^[[:blank:]]*DCB_REQUIRED=\"no\"" /etc/fcoe/cfg-${i##*/} &>/dev/null
-        [ $? -eq 0 ] && dcb="nodcb"
-        if [ "$p" ] ; then
-            grep -q "^[[:blank:]]*DCB_REQUIRED=\"no\"" /etc/fcoe/cfg-${p} &>/dev/null
+            # Some Combined Network Adapters(CNAs) implement DCB in firmware.
+            # Do not run software-based DCB or LLDP on CNAs that implement DCB.
+            # If the network interface provides hardware DCB/DCBX capabilities,
+            # DCB_REQUIRED in "/etc/fcoe/cfg-xxx" is expected to set to "no".
+            #
+            # Force "nodcb" if there's any DCB_REQUIRED="no"(child or vlan parent).
+            grep -q "^[[:blank:]]*DCB_REQUIRED=\"no\"" /etc/fcoe/cfg-${i##*/} &>/dev/null
             [ $? -eq 0 ] && dcb="nodcb"
-        fi
+            if [ "$p" ] ; then
+                grep -q "^[[:blank:]]*DCB_REQUIRED=\"no\"" /etc/fcoe/cfg-${p} &>/dev/null
+                [ $? -eq 0 ] && dcb="nodcb"
+            fi
 
-        echo "fcoe=${mac}:${dcb}"
-    done
+            echo "ifname=${ifname}:${mac}"
+            echo "fcoe=${ifname}:${dcb}:${mode}"
+        done
+    } | sort | uniq
 }
 
 # called by dracut
@@ -94,12 +104,15 @@ install() {
         local _fcoeconf=$(cmdline)
         [[ $_fcoeconf ]] && printf "%s\n" "$_fcoeconf" >> "${initdir}/etc/cmdline.d/95fcoe.conf"
     fi
+    inst_multiple /etc/fcoe/cfg-*
+
     inst "$moddir/fcoe-up.sh" "/sbin/fcoe-up"
     inst "$moddir/fcoe-edd.sh" "/sbin/fcoe-edd"
     inst "$moddir/fcoe-genrules.sh" "/sbin/fcoe-genrules.sh"
     inst_hook pre-trigger 03 "$moddir/lldpad.sh"
     inst_hook cmdline 99 "$moddir/parse-fcoe.sh"
     inst_hook cleanup 90 "$moddir/cleanup-fcoe.sh"
+    inst_hook shutdown 40 "$moddir/stop-fcoe.sh"
     dracut_need_initqueue
 }
 
diff --git a/modules.d/95fcoe/parse-fcoe.sh b/modules.d/95fcoe/parse-fcoe.sh
index 9f471848..75cca9a5 100755
--- a/modules.d/95fcoe/parse-fcoe.sh
+++ b/modules.d/95fcoe/parse-fcoe.sh
@@ -1,8 +1,8 @@
 #!/bin/sh
 #
 # Supported formats:
-# fcoe=<networkdevice>:<dcb|nodcb>
-# fcoe=<macaddress>:<dcb|nodcb>
+# fcoe=<networkdevice>:<dcb|nodcb>:<fabric|vn2vn>
+# fcoe=<macaddress>:<dcb|nodcb>:<fabric|vn2vn>
 #
 # Note currently only nodcb is supported, the dcb option is reserved for
 # future use.
@@ -10,8 +10,8 @@
 # Note letters in the macaddress must be lowercase!
 #
 # Examples:
-# fcoe=eth0:nodcb
-# fcoe=4a:3f:4c:04:f8:d7:nodcb
+# fcoe=eth0:nodcb:vn2vn
+# fcoe=4a:3f:4c:04:f8:d7:nodcb:fabric
 
 [ -z "$fcoe" ] && fcoe=$(getarg fcoe=)
 
@@ -32,11 +32,25 @@ parse_fcoe_opts() {
         2)
             fcoe_interface=$1
             fcoe_dcb=$2
+            fcoe_mode="fabric"
+            return 0
+            ;;
+        3)
+            fcoe_interface=$1
+            fcoe_dcb=$2
+            fcoe_mode=$3
             return 0
             ;;
         7)
             fcoe_mac=$1:$2:$3:$4:$5:$6
             fcoe_dcb=$7
+            fcoe_mode="fabric"
+            return 0
+            ;;
+        8)
+            fcoe_mac=$1:$2:$3:$4:$5:$6
+            fcoe_dcb=$7
+            fcoe_mode=$8
             return 0
             ;;
         *)
diff --git a/modules.d/95fcoe/stop-fcoe.sh b/modules.d/95fcoe/stop-fcoe.sh
new file mode 100755
index 00000000..d2462b34
--- /dev/null
+++ b/modules.d/95fcoe/stop-fcoe.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+for f in /sys/bus/fcoe/devices/ctlr_* ; do
+    [ -e $f ] || continue
+    echo 0 > $f/enabled
+done