[RFC,blktests,v1,1/1] nvme/050: test DNR handling on reconnect
Commit Message
When the host gets disconnected and tries to reconnect,
it should honor the DNR bit and do not retry to connect
with the same parameters.
Signed-off-by: Daniel Wagner <dwagner@suse.de>
---
tests/nvme/050 | 126 +++++++++++++++++++++++++++++++++++++++++++++
tests/nvme/050.out | 2 +
2 files changed, 128 insertions(+)
create mode 100644 tests/nvme/050
create mode 100644 tests/nvme/050.out
new file mode 100644
@@ -0,0 +1,126 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0+
+# Copyright (C) 2023 SUSE LLC
+#
+# Test DNR is handled on connnect attempt with invalid arguments.
+
+. tests/nvme/rc
+
+DESCRIPTION="test DNR is handled on connect attempt with invalid arguments"
+
+requires() {
+ _nvme_requires
+ _require_nvme_trtype tcp rdma fc
+ _require_min_cpus 2
+}
+
+nvmf_wait_for_state() {
+ local def_state_timeout=5
+ local subsys_name="$1"
+ local state="$2"
+ local timeout="${3:-$def_state_timeout}"
+ local nvmedev
+ local state_file
+ local start_time
+ local end_time
+
+ nvmedev=$(_find_nvme_dev "${subsys_name}")
+ state_file="/sys/class/nvme-fabrics/ctl/${nvmedev}/state"
+
+ start_time=$(date +%s)
+ while ! grep -q "${state}" "${state_file}"; do
+ sleep 1
+ end_time=$(date +%s)
+ if (( end_time - start_time > timeout )); then
+ echo "expected state \"${state}\" not " \
+ "reached within ${timeout} seconds"
+ return 1
+ fi
+ done
+
+ return 0
+}
+
+nvmf_wait_for_ctrl_delete() {
+ local def_state_timeout=5
+ local nvmedev="$1"
+ local timeout="${2:-$def_state_timeout}"
+ local ctrl="/sys/class/nvme-fabrics/ctl/${nvmedev}/state"
+ local start_time
+ local end_time
+
+ start_time=$(date +%s)
+ while [ -f "${ctrl}" ]; do
+ sleep 1
+ end_time=$(date +%s)
+ if (( end_time - start_time > timeout )); then
+ echo "controller \"${nvmedev}\" not deleted" \
+ "within ${timeout} seconds"
+ return 1
+ fi
+ done
+
+ return 0
+}
+
+set_nvmet_attr_qid_max() {
+ local nvmet_subsystem="$1"
+ local qid_max="$2"
+ local cfs_path="${NVMET_CFS}/subsystems/${nvmet_subsystem}"
+
+ echo "${qid_max}" > "${cfs_path}/attr_qid_max"
+}
+
+test() {
+ echo "Running ${TEST_NAME}"
+
+ _setup_nvmet
+
+ local port
+ local loop_dev
+ local file_path="$TMPDIR/img"
+ local subsys_name="blktests-subsystem-1"
+ local hostid="77b49aba-06b4-431a-9af8-75e318740f1a"
+ local hostnqn="nqn.2014-08.org.nvmexpress:uuid:${hostid}"
+ local cfs_path="${NVMET_CFS}/subsystems/${subsys_name}"
+ local nvmedev
+
+ truncate -s "${nvme_img_size}" "${file_path}"
+
+ loop_dev="$(losetup -f --show "${file_path}")"
+
+ _create_nvmet_subsystem "${subsys_name}" "${loop_dev}" \
+ "91fdba0d-f87b-4c25-b80f-db7be1418b9e"
+ port="$(_create_nvmet_port "${nvme_trtype}")"
+ _add_nvmet_subsys_to_port "${port}" "${subsys_name}"
+
+ _nvme_connect_subsys "${nvme_trtype}" "${subsys_name}" \
+ --hostnqn "${hostnqn}" \
+ --reconnect-delay 1 \
+ --ctrl-loss-tmo 10
+
+ nvmf_wait_for_state "${subsys_name}" "live"
+ nvmedev=$(_find_nvme_dev "${subsys_name}")
+
+ # Only allow connects from ${def_hostnqn}
+ echo 0 > "${cfs_path}/attr_allow_any_host"
+
+ # Force a reconnect
+ set_nvmet_attr_qid_max "${subsys_name}" 1
+
+ # The reconnect fails with the DNR bit set
+ # Thus the host should remove the controller
+ nvmf_wait_for_ctrl_delete "${nvmedev}"
+
+ _nvme_disconnect_subsys "${subsys_name}" >> "$FULL" 2>&1
+
+ _remove_nvmet_subsystem_from_port "${port}" "${subsys_name}"
+ _remove_nvmet_subsystem "${subsys_name}"
+ _remove_nvmet_port "${port}"
+
+ losetup -d "${loop_dev}"
+
+ rm "${file_path}"
+
+ echo "Test complete"
+}
new file mode 100644
@@ -0,0 +1,2 @@
+Running nvme/050
+Test complete