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@xxxxxxx> --- 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 diff --git a/tests/nvme/050 b/tests/nvme/050 new file mode 100644 index 000000000000..d33eb24e2f13 --- /dev/null +++ b/tests/nvme/050 @@ -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" +} diff --git a/tests/nvme/050.out b/tests/nvme/050.out new file mode 100644 index 000000000000..b78b05f78424 --- /dev/null +++ b/tests/nvme/050.out @@ -0,0 +1,2 @@ +Running nvme/050 +Test complete -- 2.41.0