|
|
6aee12 |
From 43e9997521d6c10ec8dae340dc117dd6cbd73a2a Mon Sep 17 00:00:00 2001
|
|
|
6aee12 |
From: Martin Wilck <mwilck@suse.com>
|
|
|
6aee12 |
Date: Fri, 16 Sep 2022 21:36:52 +0200
|
|
|
6aee12 |
Subject: [PATCH] (Cherry-picked commits:
|
|
|
6aee12 |
9664e98b5db603567d42d4d0c6e6ea1bd3d5bf24
|
|
|
6aee12 |
b3ff3f3fbce6878a754332cd4a05374e5e1156c8
|
|
|
6aee12 |
a3cf4ec92202df43adf368c7fdd12e35d304a0e4
|
|
|
6aee12 |
03921ec09e95ea49f89ae307dcca4e2e3d1bc6d6
|
|
|
6aee12 |
e93e46520dd89a7357a15441ab6b141ff9ff9aeb
|
|
|
6aee12 |
556ef46aa96650d72b2fd850a09fa04dff64bbb8
|
|
|
6aee12 |
a93968b07567a654d18b8ef2144337d803186eca
|
|
|
6aee12 |
a65fab69662d3adf52eb968411f59ebc5a173f7c
|
|
|
6aee12 |
cf8986af7d9a3ce73f330de23d5312f924acea34
|
|
|
6aee12 |
7c28e1148c086d8504caab6e70a1bcfda1bbf0b9
|
|
|
6aee12 |
b03dc850e4630c3b727f71b853a1be588507a59e
|
|
|
6aee12 |
0a4d7f9aece172f0f9a9286c94308b7e1ef8d500)
|
|
|
6aee12 |
|
|
|
6aee12 |
fix(nvmf): nvme list-subsys prints the address using commas as separator
|
|
|
6aee12 |
|
|
|
6aee12 |
nvme-cli 1.x printed the address using spaces as separator, but nvme-cli 2.x
|
|
|
6aee12 |
prints the address using commas as separator (exact output from sysfs). E.g.,
|
|
|
6aee12 |
output from `cat /sys/class/nvme/nvme0/address`:
|
|
|
6aee12 |
|
|
|
6aee12 |
traddr=nn-0x201700a09890f5bf:pn-0x201900a09890f5bf,host_traddr=nn-0x200000109b579ef5:pn-0x100000109b579ef5
|
|
|
6aee12 |
|
|
|
6aee12 |
Also, I suppress rd.nvmf.discover= cmdline option if all fields are empty.
|
|
|
6aee12 |
|
|
|
6aee12 |
fix(nvmf): don't try to validate network connections in cmdline hook
|
|
|
6aee12 |
|
|
|
6aee12 |
The cmdline hook runs before any network interfaces have been brought
|
|
|
6aee12 |
up. There's no point in trying to validate the connections at this
|
|
|
6aee12 |
stage.
|
|
|
6aee12 |
|
|
|
6aee12 |
fix(nvmf): no need to load the nvme module
|
|
|
6aee12 |
|
|
|
6aee12 |
The module "nvme" is not required for NVMeoF.
|
|
|
6aee12 |
|
|
|
6aee12 |
fix(nvmf): don't create did-setup file
|
|
|
6aee12 |
|
|
|
6aee12 |
did-setup files are meant to indicate that an interface setup
|
|
|
6aee12 |
was successful. Don't do it here.
|
|
|
6aee12 |
|
|
|
6aee12 |
fix(nvmf): don't use "finished" queue for autoconnect
|
|
|
6aee12 |
|
|
|
6aee12 |
The "finished" initqueue is for testing if everything is alright,
|
|
|
6aee12 |
not for triggering any actions.
|
|
|
6aee12 |
|
|
|
6aee12 |
fix(nvmf): make sure "rd.nvmf.discover=fc,auto" takes precedence
|
|
|
6aee12 |
|
|
|
6aee12 |
The command line may contain several rd.nvmf.discover options.
|
|
|
6aee12 |
The "fc,auto" option should take precedence.
|
|
|
6aee12 |
|
|
|
6aee12 |
fix(nvmf): avoid calling "exit" in a cmdline hook
|
|
|
6aee12 |
|
|
|
6aee12 |
"exit" should never be executed in dracut hooks, because the
|
|
|
6aee12 |
hooks are sourced by the main script.
|
|
|
6aee12 |
|
|
|
6aee12 |
fix(nvmf): run cmdline hook before parse-ip-opts.sh
|
|
|
6aee12 |
|
|
|
6aee12 |
This way we can set "rd.neednet" and have it seen by parse-ip-options.sh
|
|
|
6aee12 |
|
|
|
6aee12 |
feat(nvmf): set rd.neednet=1 if tcp records encountered
|
|
|
6aee12 |
|
|
|
6aee12 |
This is currently always the case for NBFT records.
|
|
|
6aee12 |
We can do this now, as we run before parse-ip-options.sh
|
|
|
6aee12 |
|
|
|
6aee12 |
fix(nvmf): install 8021q module unconditionally
|
|
|
6aee12 |
|
|
|
6aee12 |
In NBFT setups, VLAN can be configured in the firmware.
|
|
|
6aee12 |
Add the 8021q module in hostonly mode even if VLAN is currently
|
|
|
6aee12 |
not used to be prepared for such configuration change.
|
|
|
6aee12 |
|
|
|
6aee12 |
fix(nvmf): support /etc/nvme/config.json
|
|
|
6aee12 |
|
|
|
6aee12 |
Since nvme-cli 2.0, configuration of subsystems to connect to is
|
|
|
6aee12 |
stored under `/etc/nvme` in either `discovery.conf` or `config.json`.
|
|
|
6aee12 |
Attempt discovery also if the latter exists, but not the former.
|
|
|
6aee12 |
Also, install "config.json" if it's present on the root FS.
|
|
|
6aee12 |
|
|
|
6aee12 |
As before, "rd.nvmf.discover=fc,auto" will force either file to be ignored,
|
|
|
6aee12 |
and NBFT-defined targets take precedence if found.
|
|
|
6aee12 |
|
|
|
6aee12 |
feat(nvmf): add code for parsing the NBFT
|
|
|
6aee12 |
|
|
|
6aee12 |
Add code to parse the Nvme-oF Boot Firmware Table (NBFT) according
|
|
|
6aee12 |
to the NVM Express Boot Specification 1.0 [1]. The implementation in
|
|
|
6aee12 |
dracut follows a similar general approach as iBFT support in the
|
|
|
6aee12 |
iscsi module.
|
|
|
6aee12 |
|
|
|
6aee12 |
NBFT support requires two steps:
|
|
|
6aee12 |
|
|
|
6aee12 |
(1) Setting up the network and routing according to the
|
|
|
6aee12 |
HFI ("Host Fabric Interface") records in the NBFT,
|
|
|
6aee12 |
(2) Establishing the actual NVMe-oF connection.
|
|
|
6aee12 |
|
|
|
6aee12 |
(1) is accomplished by reading the NBFT using JSON output from
|
|
|
6aee12 |
the "nvme nbft show" command, and transforming it into command
|
|
|
6aee12 |
line options ("ip=", "rd.neednet", etc.) understood by dracut's
|
|
|
6aee12 |
network module and its backends. The resulting network setup code
|
|
|
6aee12 |
is backend-agnostic. It has been tested with the "network-legacy"
|
|
|
6aee12 |
and "network-manager" network backend modules. The network setup
|
|
|
6aee12 |
code supports IPv4 and IPv6 with static, RA, or DHCP configurations,
|
|
|
6aee12 |
802.1q VLANs, and simple routing / gateway setup.
|
|
|
6aee12 |
|
|
|
6aee12 |
(2) is done using the "nvme connect-all" command [2] in the netroot handler,
|
|
|
6aee12 |
which is invoked by networking backends when an interface gets fully
|
|
|
6aee12 |
configured. This patch adds support for "netboot=nbft". The "nbftroot"
|
|
|
6aee12 |
handler calls nvmf-autoconnect.sh, which contains the actual connect
|
|
|
6aee12 |
logic. nvmf-autoconnect.sh itself is preserved, because there are
|
|
|
6aee12 |
other NVMe-oF setups like NVMe over FC which don't depend on the
|
|
|
6aee12 |
network.
|
|
|
6aee12 |
|
|
|
6aee12 |
The various ways to configure NVMe-oF are prioritized like this:
|
|
|
6aee12 |
|
|
|
6aee12 |
1 FC autoconnect from kernel commandline (rd.nvmf.discover=fc,auto)
|
|
|
6aee12 |
2 NBFT, if present
|
|
|
6aee12 |
3 discovery.conf or config.json, if present, and cmdline.d parameters,
|
|
|
6aee12 |
if present (rd.nvmf.discovery=...)
|
|
|
6aee12 |
4 FC autoconnect (without kernel command line)
|
|
|
6aee12 |
|
|
|
6aee12 |
The reason for this priorization is that in the initial RAM fs, we try
|
|
|
6aee12 |
to activate only those connections that are necessary to mount the root
|
|
|
6aee12 |
file system. This avoids confusion, possible contradicting or ambiguous
|
|
|
6aee12 |
configuration, and timeouts from unavailable targets.
|
|
|
6aee12 |
|
|
|
6aee12 |
A retry logic is implemented for enabling the NVMe-oF connections,
|
|
|
6aee12 |
using the "settled" initqueue, the netroot handler, and eventually, the
|
|
|
6aee12 |
"timeout" initqueue. This is similar to the retry logic of the iscsi module.
|
|
|
6aee12 |
In the "timeout" case, connection to all possible NVMe-oF subsystems
|
|
|
6aee12 |
is attempted.
|
|
|
6aee12 |
|
|
|
6aee12 |
Two new command line parameters are introduced to make it possible to
|
|
|
6aee12 |
change the priorities above:
|
|
|
6aee12 |
|
|
|
6aee12 |
- "rd.nvmf.nonbft" causes the NBFT to be ignored,
|
|
|
6aee12 |
- "rd.nvmf.nostatic" causes any statically configured NVMe-oF targets
|
|
|
6aee12 |
(config.json, discovery.conf, and cmdline.d) to be ignored.
|
|
|
6aee12 |
|
|
|
6aee12 |
These parameters may be helpful to skip attempts to set up broken
|
|
|
6aee12 |
configurations.
|
|
|
6aee12 |
|
|
|
6aee12 |
At initramfs build time, the nvmf module is now enabled if an NBFT
|
|
|
6aee12 |
table is detected in the system.
|
|
|
6aee12 |
|
|
|
6aee12 |
[1] https://nvmexpress.org/wp-content/uploads/NVM-Express-Boot-Specification-2022.11.15-Ratified.pdf
|
|
|
6aee12 |
[2] NBFT support in nvme-cli requires the latest upstream code (> v2.4).
|
|
|
6aee12 |
|
|
|
6aee12 |
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
|
|
6aee12 |
Co-authored-by: John Meneghini <jmeneghi@redhat.com>
|
|
|
6aee12 |
Co-authored-by: Charles Rose <charles.rose@dell.com>
|
|
|
6aee12 |
---
|
|
|
6aee12 |
man/dracut.cmdline.7.asc | 9 +
|
|
|
6aee12 |
modules.d/95nvmf/module-setup.sh | 36 ++-
|
|
|
6aee12 |
modules.d/95nvmf/nbftroot.sh | 5 +
|
|
|
6aee12 |
modules.d/95nvmf/nvmf-autoconnect.sh | 55 +++-
|
|
|
6aee12 |
.../95nvmf/parse-nvmf-boot-connections.sh | 237 ++++++++++++++++--
|
|
|
6aee12 |
create mode 100755 modules.d/95nvmf/nbftroot.sh
|
|
|
6aee12 |
|
|
|
6aee12 |
diff --git a/man/dracut.cmdline.7.asc b/man/dracut.cmdline.7.asc
|
|
|
6aee12 |
index 93861c56..47a6b6c7 100644
|
|
|
6aee12 |
--- a/man/dracut.cmdline.7.asc
|
|
|
6aee12 |
+++ b/man/dracut.cmdline.7.asc
|
|
|
6aee12 |
@@ -898,6 +898,15 @@ NVMf
|
|
|
6aee12 |
**rd.nonvmf**::
|
|
|
6aee12 |
Disable NVMf
|
|
|
6aee12 |
|
|
|
6aee12 |
+**rd.nvmf.nonbft**::
|
|
|
6aee12 |
+ Disable connecting to targets from the NVMe Boot Firmware Table. Without
|
|
|
6aee12 |
+ this parameter, NBFT connections will take precedence over _rd.nvmf.discover_.
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+**rd.nvmf.nostatic**::
|
|
|
6aee12 |
+ Disable connecting to targets that have been statically configured when
|
|
|
6aee12 |
+ the initramfs was built. Targets specified with rd.nvmf.discover on the
|
|
|
6aee12 |
+ kernel command line will still be tried.
|
|
|
6aee12 |
+
|
|
|
6aee12 |
**rd.nvmf.hostnqn=**__<hostNQN>__::
|
|
|
6aee12 |
NVMe host NQN to use
|
|
|
6aee12 |
|
|
|
6aee12 |
diff --git a/modules.d/95nvmf/module-setup.sh b/modules.d/95nvmf/module-setup.sh
|
|
|
6aee12 |
index 476b7f7..1dd2ca5 100755
|
|
|
6aee12 |
--- a/modules.d/95nvmf/module-setup.sh
|
|
|
6aee12 |
+++ b/modules.d/95nvmf/module-setup.sh
|
|
|
6aee12 |
@@ -2,7 +2,7 @@
|
|
|
6aee12 |
|
|
|
6aee12 |
# called by dracut
|
|
|
6aee12 |
check() {
|
|
|
6aee12 |
- require_binaries nvme || return 1
|
|
|
6aee12 |
+ require_binaries nvme jq || return 1
|
|
|
6aee12 |
[ -f /etc/nvme/hostnqn ] || return 255
|
|
|
6aee12 |
[ -f /etc/nvme/hostid ] || return 255
|
|
|
6aee12 |
|
|
|
6aee12 |
@@ -18,24 +18,34 @@ check() {
|
|
|
6aee12 |
for d in device/nvme*; do
|
|
|
6aee12 |
[ -L "$d" ] || continue
|
|
|
6aee12 |
if readlink "$d" | grep -q nvme-fabrics; then
|
|
|
6aee12 |
- read -r trtype < "$d"/transport
|
|
|
6aee12 |
+ trtype=$(cat "$d"/transport)
|
|
|
6aee12 |
break
|
|
|
6aee12 |
fi
|
|
|
6aee12 |
done
|
|
|
6aee12 |
[[ $trtype == "fc" ]] || [[ $trtype == "tcp" ]] || [[ $trtype == "rdma" ]]
|
|
|
6aee12 |
}
|
|
|
6aee12 |
|
|
|
6aee12 |
+ has_nbft() {
|
|
|
6aee12 |
+ local f found=
|
|
|
6aee12 |
+ for f in /sys/firmware/acpi/tables/NBFT*; do
|
|
|
6aee12 |
+ [ -f "$f" ] || continue
|
|
|
6aee12 |
+ found=1
|
|
|
6aee12 |
+ break
|
|
|
6aee12 |
+ done
|
|
|
6aee12 |
+ [[ $found ]]
|
|
|
6aee12 |
+ }
|
|
|
6aee12 |
+
|
|
|
6aee12 |
[[ $hostonly ]] || [[ $mount_needs ]] && {
|
|
|
6aee12 |
pushd . > /dev/null
|
|
|
6aee12 |
for_each_host_dev_and_slaves is_nvmf
|
|
|
6aee12 |
local _is_nvmf=$?
|
|
|
6aee12 |
popd > /dev/null || exit
|
|
|
6aee12 |
[[ $_is_nvmf == 0 ]] || return 255
|
|
|
6aee12 |
- if [ ! -f /sys/class/fc/fc_udev_device/nvme_discovery ]; then
|
|
|
6aee12 |
- if [ ! -f /etc/nvme/discovery.conf ]; then
|
|
|
6aee12 |
- echo "No discovery arguments present"
|
|
|
6aee12 |
- return 255
|
|
|
6aee12 |
- fi
|
|
|
6aee12 |
+ if [ ! -f /sys/class/fc/fc_udev_device/nvme_discovery ] \
|
|
|
6aee12 |
+ && [ ! -f /etc/nvme/discovery.conf ] \
|
|
|
6aee12 |
+ && [ ! -f /etc/nvme/config.json ] && ! has_nbft; then
|
|
|
6aee12 |
+ echo "No discovery arguments present"
|
|
|
6aee12 |
+ return 255
|
|
|
6aee12 |
fi
|
|
|
6aee12 |
}
|
|
|
6aee12 |
return 0
|
|
|
6aee12 |
@@ -50,7 +60,7 @@ depends() {
|
|
|
6aee12 |
# called by dracut
|
|
|
6aee12 |
installkernel() {
|
|
|
6aee12 |
instmods nvme_fc lpfc qla2xxx
|
|
|
6aee12 |
- hostonly="" instmods nvme_tcp nvme_fabrics
|
|
|
6aee12 |
+ hostonly="" instmods nvme_tcp nvme_fabrics 8021q
|
|
|
6aee12 |
}
|
|
|
6aee12 |
|
|
|
6aee12 |
# called by dracut
|
|
|
6aee12 |
@@ -75,7 +85,7 @@ cmdline() {
|
|
|
6aee12 |
for d in device/nvme*; do
|
|
|
6aee12 |
[ -L "$d" ] || continue
|
|
|
6aee12 |
if readlink "$d" | grep -q nvme-fabrics; then
|
|
|
6aee12 |
- read -r trtype < "$d"/transport
|
|
|
6aee12 |
+ trtype=$(cat "$d"/transport)
|
|
|
6aee12 |
break
|
|
|
6aee12 |
fi
|
|
|
6aee12 |
done
|
|
|
6aee12 |
@@ -98,11 +108,11 @@ cmdline() {
|
|
|
6aee12 |
}
|
|
|
6aee12 |
|
|
|
6aee12 |
if [ -f /etc/nvme/hostnqn ]; then
|
|
|
6aee12 |
- read -r _hostnqn < /etc/nvme/hostnqn
|
|
|
6aee12 |
+ _hostnqn=$(cat /etc/nvme/hostnqn)
|
|
|
6aee12 |
echo -n " rd.nvmf.hostnqn=${_hostnqn}"
|
|
|
6aee12 |
fi
|
|
|
6aee12 |
if [ -f /etc/nvme/hostid ]; then
|
|
|
6aee12 |
- read -r _hostid < /etc/nvme/hostid
|
|
|
6aee12 |
+ _hostid=$(cat /etc/nvme/hostid)
|
|
|
6aee12 |
echo -n " rd.nvmf.hostid=${_hostid}"
|
|
|
6aee12 |
fi
|
|
|
6aee12 |
|
|
|
6aee12 |
@@ -126,10 +136,12 @@ install() {
|
|
|
6aee12 |
inst_multiple ip sed
|
|
|
6aee12 |
|
|
|
6aee12 |
inst_script "${moddir}/nvmf-autoconnect.sh" /sbin/nvmf-autoconnect.sh
|
|
|
6aee12 |
+ inst_script "${moddir}/nbftroot.sh" /sbin/nbftroot
|
|
|
6aee12 |
|
|
|
6aee12 |
- inst_multiple nvme
|
|
|
6aee12 |
+ inst_multiple nvme jq
|
|
|
6aee12 |
inst_hook cmdline 92 "$moddir/parse-nvmf-boot-connections.sh"
|
|
|
6aee12 |
inst_simple "/etc/nvme/discovery.conf"
|
|
|
6aee12 |
+ inst_simple "/etc/nvme/config.json"
|
|
|
6aee12 |
inst_rules /usr/lib/udev/rules.d/71-nvmf-iopolicy-netapp.rules
|
|
|
6aee12 |
inst_rules "$moddir/95-nvmf-initqueue.rules"
|
|
|
6aee12 |
dracut_need_initqueue
|
|
|
6aee12 |
diff --git a/modules.d/95nvmf/nbftroot.sh b/modules.d/95nvmf/nbftroot.sh
|
|
|
6aee12 |
new file mode 100755
|
|
|
6aee12 |
index 0000000..0f33499
|
|
|
6aee12 |
--- /dev/null
|
|
|
6aee12 |
+++ b/modules.d/95nvmf/nbftroot.sh
|
|
|
6aee12 |
@@ -0,0 +1,5 @@
|
|
|
6aee12 |
+#! /bin/sh
|
|
|
6aee12 |
+# This script is called from /sbin/netroot
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+/sbin/nvmf-autoconnect.sh online
|
|
|
6aee12 |
+exit 0
|
|
|
6aee12 |
diff --git a/modules.d/95nvmf/nvmf-autoconnect.sh b/modules.d/95nvmf/nvmf-autoconnect.sh
|
|
|
6aee12 |
index c8f676a..35ee948 100755
|
|
|
6aee12 |
--- a/modules.d/95nvmf/nvmf-autoconnect.sh
|
|
|
6aee12 |
+++ b/modules.d/95nvmf/nvmf-autoconnect.sh
|
|
|
6aee12 |
@@ -1,5 +1,54 @@
|
|
|
6aee12 |
-#!/bin/bash
|
|
|
6aee12 |
+#!/bin/sh
|
|
|
6aee12 |
+# Argument $1 is "settled", "online", or "timeout", indicating
|
|
|
6aee12 |
+# the queue from which the script is called.
|
|
|
6aee12 |
+# In the "timeout" case, try everything.
|
|
|
6aee12 |
+# Otherwise, try options according to the priorities below.
|
|
|
6aee12 |
|
|
|
6aee12 |
-[ -f /sys/class/fc/fc_udev_device/nvme_discovery ] || exit 1
|
|
|
6aee12 |
-echo add > /sys/class/fc/fc_udev_device/nvme_discovery
|
|
|
6aee12 |
+[ "$RD_DEBUG" != yes ] || set -x
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+if [ "$1" = timeout ]; then
|
|
|
6aee12 |
+ [ ! -f /sys/class/fc/fc_udev_device/nvme_discovery ] \
|
|
|
6aee12 |
+ || echo add > /sys/class/fc/fc_udev_device/nvme_discovery
|
|
|
6aee12 |
+ /usr/sbin/nvme connect-all
|
|
|
6aee12 |
+ exit 0
|
|
|
6aee12 |
+fi
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+NVMF_HOSTNQN_OK=
|
|
|
6aee12 |
+[ ! -f "/etc/nvme/hostnqn" ] || [ ! -f "/etc/nvme/hostid" ] || NVMF_HOSTNQN_OK=1
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+# Only nvme-cli 2.5 or newer supports the options --nbft and --no-nbft
|
|
|
6aee12 |
+# for the connect-all command.
|
|
|
6aee12 |
+# Make sure we don't use unsupported options with earlier versions.
|
|
|
6aee12 |
+NBFT_SUPPORTED=
|
|
|
6aee12 |
+# shellcheck disable=SC2016
|
|
|
6aee12 |
+/usr/sbin/nvme connect-all --help 2>&1 | sed -n '/[[:space:]]--nbft[[:space:]]/q1;$q0' \
|
|
|
6aee12 |
+ || NBFT_SUPPORTED=1
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+if [ -e /tmp/nvmf-fc-auto ] && [ "$NVMF_HOSTNQN_OK" ] \
|
|
|
6aee12 |
+ && [ -f /sys/class/fc/fc_udev_device/nvme_discovery ]; then
|
|
|
6aee12 |
+ # prio 1: cmdline override "rd.nvmf.discovery=fc,auto"
|
|
|
6aee12 |
+ echo add > /sys/class/fc/fc_udev_device/nvme_discovery
|
|
|
6aee12 |
+ exit 0
|
|
|
6aee12 |
+fi
|
|
|
6aee12 |
+if [ "$NBFT_SUPPORTED" ] && [ -e /tmp/valid_nbft_entry_found ]; then
|
|
|
6aee12 |
+ # prio 2: NBFT
|
|
|
6aee12 |
+ /usr/sbin/nvme connect-all --nbft
|
|
|
6aee12 |
+ exit 0
|
|
|
6aee12 |
+fi
|
|
|
6aee12 |
+if [ -f /etc/nvme/discovery.conf ] || [ -f /etc/nvme/config.json ] \
|
|
|
6aee12 |
+ && [ "$NVMF_HOSTNQN_OK" ]; then
|
|
|
6aee12 |
+ # prio 3: configuration from initrd and/or kernel command line
|
|
|
6aee12 |
+ # We can get here even if "rd.nvmf.nonbft" was given, thus use --no-nbft
|
|
|
6aee12 |
+ if [ "$NBFT_SUPPORTED" ]; then
|
|
|
6aee12 |
+ /usr/sbin/nvme connect-all --no-nbft
|
|
|
6aee12 |
+ else
|
|
|
6aee12 |
+ /usr/sbin/nvme connect-all
|
|
|
6aee12 |
+ fi
|
|
|
6aee12 |
+ exit 0
|
|
|
6aee12 |
+fi
|
|
|
6aee12 |
+if [ "$NVMF_HOSTNQN_OK" ] \
|
|
|
6aee12 |
+ && [ -f /sys/class/fc/fc_udev_device/nvme_discovery ]; then
|
|
|
6aee12 |
+ # prio 4: no discovery entries, try NVMeoFC autoconnect
|
|
|
6aee12 |
+ echo add > /sys/class/fc/fc_udev_device/nvme_discovery
|
|
|
6aee12 |
+fi
|
|
|
6aee12 |
exit 0
|
|
|
6aee12 |
diff --git a/modules.d/95nvmf/parse-nvmf-boot-connections.sh b/modules.d/95nvmf/parse-nvmf-boot-connections.sh
|
|
|
6aee12 |
index 6b26f76..6601837 100755
|
|
|
6aee12 |
--- a/modules.d/95nvmf/parse-nvmf-boot-connections.sh
|
|
|
6aee12 |
+++ b/modules.d/95nvmf/parse-nvmf-boot-connections.sh
|
|
|
6aee12 |
@@ -17,13 +17,225 @@
|
|
|
6aee12 |
# specify any discover parameters for FC.
|
|
|
6aee12 |
#
|
|
|
6aee12 |
|
|
|
6aee12 |
-type is_ip > /dev/null 2>&1 || . /lib/net-lib.sh
|
|
|
6aee12 |
+command -v getarg > /dev/null || . /lib/dracut-lib.sh
|
|
|
6aee12 |
+command -v is_ip > /dev/null || . /lib/net-lib.sh
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+## Sample NBFT output from nvme show-nbft -H -s -d -o json
|
|
|
6aee12 |
+# [
|
|
|
6aee12 |
+# {
|
|
|
6aee12 |
+# "filename":"/sys/firmware/acpi/tables/NBFT",
|
|
|
6aee12 |
+# "host":{
|
|
|
6aee12 |
+# "nqn":"nqn.2014-08.org.nvmexpress:uuid:d6f07002-7eb5-4841-a185-400e296afae4",
|
|
|
6aee12 |
+# "id":"111919da-21ea-cc4e-bafe-216d8372dd31",
|
|
|
6aee12 |
+# "host_id_configured":0,
|
|
|
6aee12 |
+# "host_nqn_configured":0,
|
|
|
6aee12 |
+# "primary_admin_host_flag":"not indicated"
|
|
|
6aee12 |
+# },
|
|
|
6aee12 |
+# "subsystem":[
|
|
|
6aee12 |
+# {
|
|
|
6aee12 |
+# "index":1,
|
|
|
6aee12 |
+# "num_hfis":1,
|
|
|
6aee12 |
+# "hfis":[
|
|
|
6aee12 |
+# 1
|
|
|
6aee12 |
+# ],
|
|
|
6aee12 |
+# "transport":"tcp",
|
|
|
6aee12 |
+# "transport_address":"192.168.100.216",
|
|
|
6aee12 |
+# "transport_svcid":"4420",
|
|
|
6aee12 |
+# "subsys_port_id":0,
|
|
|
6aee12 |
+# "nsid":1,
|
|
|
6aee12 |
+# "nid_type":"uuid",
|
|
|
6aee12 |
+# "nid":"424d1c8a-8ef9-4681-b2fc-8c343bd8fa69",
|
|
|
6aee12 |
+# "subsys_nqn":"timberland-01",
|
|
|
6aee12 |
+# "controller_id":0,
|
|
|
6aee12 |
+# "asqsz":0,
|
|
|
6aee12 |
+# "pdu_header_digest_required":0,
|
|
|
6aee12 |
+# "data_digest_required":0
|
|
|
6aee12 |
+# }
|
|
|
6aee12 |
+# ],
|
|
|
6aee12 |
+# "hfi":[
|
|
|
6aee12 |
+# {
|
|
|
6aee12 |
+# "index":1,
|
|
|
6aee12 |
+# "transport":"tcp",
|
|
|
6aee12 |
+# "pcidev":"0:0:2.0",
|
|
|
6aee12 |
+# "mac_addr":"52:54:00:4f:97:e9",
|
|
|
6aee12 |
+# "vlan":0,
|
|
|
6aee12 |
+# "ip_origin":63,
|
|
|
6aee12 |
+# "ipaddr":"192.168.100.217",
|
|
|
6aee12 |
+# "subnet_mask_prefix":24,
|
|
|
6aee12 |
+# "gateway_ipaddr":"0.0.0.0",
|
|
|
6aee12 |
+# "route_metric":0,
|
|
|
6aee12 |
+# "primary_dns_ipaddr":"0.0.0.0",
|
|
|
6aee12 |
+# "secondary_dns_ipaddr":"0.0.0.0",
|
|
|
6aee12 |
+# "dhcp_server_ipaddr":"",
|
|
|
6aee12 |
+# "this_hfi_is_default_route":1
|
|
|
6aee12 |
+# }
|
|
|
6aee12 |
+# ],
|
|
|
6aee12 |
+# "discovery":[
|
|
|
6aee12 |
+# ]
|
|
|
6aee12 |
+# }
|
|
|
6aee12 |
+# ]
|
|
|
6aee12 |
+#
|
|
|
6aee12 |
+# If the IP address is derived from DHCP, it sets the field
|
|
|
6aee12 |
+# "hfi.dhcp_server_ipaddr" to a non-emtpy value.
|
|
|
6aee12 |
+#
|
|
|
6aee12 |
+#
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+nbft_run_jq() {
|
|
|
6aee12 |
+ local st
|
|
|
6aee12 |
+ local opts="-e"
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+ while [ $# -gt 0 ]; do
|
|
|
6aee12 |
+ case $1 in
|
|
|
6aee12 |
+ -*)
|
|
|
6aee12 |
+ opts="$opts $1"
|
|
|
6aee12 |
+ ;;
|
|
|
6aee12 |
+ *)
|
|
|
6aee12 |
+ break
|
|
|
6aee12 |
+ ;;
|
|
|
6aee12 |
+ esac
|
|
|
6aee12 |
+ shift
|
|
|
6aee12 |
+ done
|
|
|
6aee12 |
+ # Not quoting is intentional here. We won't get glob expressions passed.
|
|
|
6aee12 |
+ # shellcheck disable=SC2086
|
|
|
6aee12 |
+ jq $opts "$1" << EOF
|
|
|
6aee12 |
+$2
|
|
|
6aee12 |
+EOF
|
|
|
6aee12 |
+ st=$?
|
|
|
6aee12 |
+ if [ $st -ne 0 ]; then
|
|
|
6aee12 |
+ warn "NBFT: jq error while processing \"$1\""
|
|
|
6aee12 |
+ return $st
|
|
|
6aee12 |
+ else
|
|
|
6aee12 |
+ return 0
|
|
|
6aee12 |
+ fi
|
|
|
6aee12 |
+}
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+nbft_check_empty_address() {
|
|
|
6aee12 |
+ # suppress meaningless or empty IP addresses
|
|
|
6aee12 |
+ # "null" is returned by jq if no match found for expression
|
|
|
6aee12 |
+ case $1 in
|
|
|
6aee12 |
+ null | "::" | "0.0.0.0") ;;
|
|
|
6aee12 |
+ *)
|
|
|
6aee12 |
+ echo "$1"
|
|
|
6aee12 |
+ ;;
|
|
|
6aee12 |
+ esac
|
|
|
6aee12 |
+}
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+nbft_parse_hfi() {
|
|
|
6aee12 |
+ # false positive of shellcheck - no expansion in variable assignments
|
|
|
6aee12 |
+ # shellcheck disable=2086
|
|
|
6aee12 |
+ local hfi_json=$1
|
|
|
6aee12 |
+ local mac iface ipaddr prefix vlan gateway dns1 dns2 hostname adrfam dhcp
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+ mac=$(nbft_run_jq -r .mac_addr "$hfi_json") || return 1
|
|
|
6aee12 |
+ iface=$(set_ifname nbft "$mac")
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+ vlan=$(nbft_run_jq .vlan "$hfi_json") || vlan=0
|
|
|
6aee12 |
+ # treat VLAN zero as "no vlan"
|
|
|
6aee12 |
+ [ "$vlan" -ne 0 ] || vlan=
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+ [ ! -e /tmp/net."${iface}${vlan:+.$vlan}".has_ibft_config ] || return 0
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+ dhcp=$(nbft_run_jq -r .dhcp_server_ipaddr "$hfi_json")
|
|
|
6aee12 |
+ # We need to check $? here as the above is an assignment
|
|
|
6aee12 |
+ # shellcheck disable=2181
|
|
|
6aee12 |
+ if [ $? -eq 0 ] && [ "$dhcp" ] && [ "$dhcp" != null ]; then
|
|
|
6aee12 |
+ case $dhcp in
|
|
|
6aee12 |
+ *:*)
|
|
|
6aee12 |
+ echo ip="$iface${vlan:+.$vlan}:dhcp6"
|
|
|
6aee12 |
+ ;;
|
|
|
6aee12 |
+ *.*.*.*)
|
|
|
6aee12 |
+ echo ip="$iface${vlan:+.$vlan}:dhcp"
|
|
|
6aee12 |
+ ;;
|
|
|
6aee12 |
+ *)
|
|
|
6aee12 |
+ warn "Invalid value for dhcp_server_ipaddr: $dhcp"
|
|
|
6aee12 |
+ return 1
|
|
|
6aee12 |
+ ;;
|
|
|
6aee12 |
+ esac
|
|
|
6aee12 |
+ else
|
|
|
6aee12 |
+ ipaddr=$(nbft_run_jq -r .ipaddr "$hfi_json") || return 1
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+ case $ipaddr in
|
|
|
6aee12 |
+ *.*.*.*)
|
|
|
6aee12 |
+ adrfam=ipv4
|
|
|
6aee12 |
+ ;;
|
|
|
6aee12 |
+ *:*)
|
|
|
6aee12 |
+ adrfam=ipv6
|
|
|
6aee12 |
+ ;;
|
|
|
6aee12 |
+ *)
|
|
|
6aee12 |
+ warn "invalid address: $ipaddr"
|
|
|
6aee12 |
+ return 1
|
|
|
6aee12 |
+ ;;
|
|
|
6aee12 |
+ esac
|
|
|
6aee12 |
+ prefix=$(nbft_run_jq -r .subnet_mask_prefix "$hfi_json")
|
|
|
6aee12 |
+ # Need to check $? here as he above is an assignment
|
|
|
6aee12 |
+ # shellcheck disable=2181
|
|
|
6aee12 |
+ if [ $? -ne 0 ] && [ "$adrfam" = ipv6 ]; then
|
|
|
6aee12 |
+ prefix=128
|
|
|
6aee12 |
+ fi
|
|
|
6aee12 |
+ # Use brackets for IPv6
|
|
|
6aee12 |
+ if [ "$adrfam" = ipv6 ]; then
|
|
|
6aee12 |
+ ipaddr="[$ipaddr]"
|
|
|
6aee12 |
+ fi
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+ gateway=$(nbft_check_empty_address \
|
|
|
6aee12 |
+ "$(nbft_run_jq -r .gateway_ipaddr "$hfi_json")")
|
|
|
6aee12 |
+ dns1=$(nbft_check_empty_address \
|
|
|
6aee12 |
+ "$(nbft_run_jq -r .primary_dns_ipaddr "$hfi_json")")
|
|
|
6aee12 |
+ dns2=$(nbft_check_empty_address \
|
|
|
6aee12 |
+ "$(nbft_run_jq -r .secondary_dns_ipaddr "$hfi_json")")
|
|
|
6aee12 |
+ hostname=$(nbft_run_jq -r .host_name "$hfi_json" 2> /dev/null) || hostname=
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+ echo "ip=$ipaddr::$gateway:$prefix:$hostname:$iface${vlan:+.$vlan}:none${dns1:+:$dns1}${dns2:+:$dns2}"
|
|
|
6aee12 |
+ fi
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+ if [ "$vlan" ]; then
|
|
|
6aee12 |
+ echo "vlan=$iface.$vlan:$iface"
|
|
|
6aee12 |
+ echo "$mac" > "/tmp/net.$iface.$vlan.has_ibft_config"
|
|
|
6aee12 |
+ else
|
|
|
6aee12 |
+ echo "$mac" > "/tmp/net.$iface.has_ibft_config"
|
|
|
6aee12 |
+ fi
|
|
|
6aee12 |
+ : > /tmp/valid_nbft_entry_found
|
|
|
6aee12 |
+}
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+nbft_parse() {
|
|
|
6aee12 |
+ local nbft_json n_nbft all_hfi_json n_hfi
|
|
|
6aee12 |
+ local j=0 i
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+ nbft_json=$(nvme nbft show -H -o json) || return 0
|
|
|
6aee12 |
+ n_nbft=$(nbft_run_jq ". | length" "$nbft_json") || return 0
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+ while [ "$j" -lt "$n_nbft" ]; do
|
|
|
6aee12 |
+ all_hfi_json=$(nbft_run_jq ".[$j].hfi" "$nbft_json") || continue
|
|
|
6aee12 |
+ n_hfi=$(nbft_run_jq ". | length" "$all_hfi_json") || continue
|
|
|
6aee12 |
+ i=0
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+ while [ "$i" -lt "$n_hfi" ]; do
|
|
|
6aee12 |
+ nbft_parse_hfi "$(nbft_run_jq ".[$i]" "$all_hfi_json")"
|
|
|
6aee12 |
+ i=$((i + 1))
|
|
|
6aee12 |
+ done
|
|
|
6aee12 |
+ j=$((j + 1))
|
|
|
6aee12 |
+ done >> /etc/cmdline.d/40-nbft.conf
|
|
|
6aee12 |
+}
|
|
|
6aee12 |
|
|
|
6aee12 |
if getargbool 0 rd.nonvmf; then
|
|
|
6aee12 |
warn "rd.nonvmf=0: skipping nvmf"
|
|
|
6aee12 |
return 0
|
|
|
6aee12 |
fi
|
|
|
6aee12 |
|
|
|
6aee12 |
+if getargbool 0 rd.nvmf.nostatic; then
|
|
|
6aee12 |
+ rm -f /etc/cmdline.d/95nvmf-args.conf
|
|
|
6aee12 |
+ rm -f /etc/nvme/discovery.conf /etc/nvme/config.json
|
|
|
6aee12 |
+fi
|
|
|
6aee12 |
+
|
|
|
6aee12 |
+if ! getargbool 0 rd.nvmf.nonbft; then
|
|
|
6aee12 |
+ for _x in /sys/firmware/acpi/tables/NBFT*; do
|
|
|
6aee12 |
+ if [ -f "$_x" ]; then
|
|
|
6aee12 |
+ nbft_parse
|
|
|
6aee12 |
+ break
|
|
|
6aee12 |
+ fi
|
|
|
6aee12 |
+ done
|
|
|
6aee12 |
+fi
|
|
|
6aee12 |
+
|
|
|
6aee12 |
initqueue --onetime modprobe --all -b -q nvme_tcp nvme_core nvme_fabrics
|
|
|
6aee12 |
|
|
|
6aee12 |
parse_nvmf_discover() {
|
|
|
6aee12 |
@@ -66,7 +278,7 @@ parse_nvmf_discover() {
|
|
|
6aee12 |
: > /tmp/nvmf_needs_network
|
|
|
6aee12 |
elif [ "$trtype" = "fc" ]; then
|
|
|
6aee12 |
if [ "$traddr" = "auto" ]; then
|
|
|
6aee12 |
- rm /etc/nvme/discovery.conf
|
|
|
6aee12 |
+ rm -f /etc/nvme/discovery.conf /etc/nvme/config.json
|
|
|
6aee12 |
return 1
|
|
|
6aee12 |
fi
|
|
|
6aee12 |
if [ "$hosttraddr" = "none" ]; then
|
|
|
6aee12 |
@@ -94,26 +306,21 @@ if [ -n "$nvmf_hostid" ]; then
|
|
|
6aee12 |
echo "$nvmf_hostid" > /etc/nvme/hostid
|
|
|
6aee12 |
fi
|
|
|
6aee12 |
|
|
|
6aee12 |
-NVMF_FC_AUTO=
|
|
|
6aee12 |
+rm -f /tmp/nvmf-fc-auto
|
|
|
6aee12 |
for d in $(getargs rd.nvmf.discover -d nvmf.discover=); do
|
|
|
6aee12 |
parse_nvmf_discover "$d" || {
|
|
|
6aee12 |
- NVMF_FC_AUTO=1
|
|
|
6aee12 |
+ : > /tmp/nvmf-fc-auto
|
|
|
6aee12 |
break
|
|
|
6aee12 |
}
|
|
|
6aee12 |
done
|
|
|
6aee12 |
|
|
|
6aee12 |
-if [ -e /tmp/nvmf_needs_network ]; then
|
|
|
6aee12 |
+if [ -e /tmp/nvmf_needs_network ] || [ -e /tmp/valid_nbft_entry_found ]; then
|
|
|
6aee12 |
echo "rd.neednet=1" > /etc/cmdline.d/nvmf-neednet.conf
|
|
|
6aee12 |
+ # netroot is a global variable that is present in all "sourced" scripts
|
|
|
6aee12 |
+ # shellcheck disable=SC2034
|
|
|
6aee12 |
+ netroot=nbft
|
|
|
6aee12 |
rm -f /tmp/nvmf_needs_network
|
|
|
6aee12 |
fi
|
|
|
6aee12 |
|
|
|
6aee12 |
-# Host NQN and host id are mandatory for NVMe-oF
|
|
|
6aee12 |
-if [ -f "/etc/nvme/hostnqn" ] && [ -f "/etc/nvme/hostid" ]; then
|
|
|
6aee12 |
-
|
|
|
6aee12 |
- # If no nvme command line arguments present, try autodiscovery
|
|
|
6aee12 |
- if [ $NVMF_FC_AUTO ] || [ ! -f "/etc/nvme/discovery.conf" ]; then
|
|
|
6aee12 |
- /sbin/initqueue --settled --onetime --unique --name nvme-fc-autoconnect /sbin/nvmf-autoconnect.sh
|
|
|
6aee12 |
- else
|
|
|
6aee12 |
- /sbin/initqueue --settled --onetime --unique --name nvme-discover /usr/sbin/nvme connect-all
|
|
|
6aee12 |
- fi
|
|
|
6aee12 |
-fi
|
|
|
6aee12 |
+/sbin/initqueue --settled --onetime --name nvmf-connect-settled /sbin/nvmf-autoconnect.sh settled
|
|
|
6aee12 |
+/sbin/initqueue --timeout --onetime --name nvmf-connect-timeout /sbin/nvmf-autoconnect.sh timeout
|
|
|
6aee12 |
--
|
|
|
6aee12 |
2.39.1
|
|
|
6aee12 |
|