[PATCH 1/6] nvmeof-tcp/001: simple test for nvmeof-tcp connection
Hannes Reinecke
hare at suse.de
Fri Nov 12 06:45:05 PST 2021
Signed-off-by: Hannes Reinecke <hare at suse.de>
---
tests/nvmeof-tcp/001 | 55 +++++++
tests/nvmeof-tcp/001.out | 6 +
tests/nvmeof-tcp/rc | 347 +++++++++++++++++++++++++++++++++++++++
3 files changed, 408 insertions(+)
create mode 100644 tests/nvmeof-tcp/001
create mode 100644 tests/nvmeof-tcp/001.out
create mode 100644 tests/nvmeof-tcp/rc
diff --git a/tests/nvmeof-tcp/001 b/tests/nvmeof-tcp/001
new file mode 100644
index 0000000..39f4108
--- /dev/null
+++ b/tests/nvmeof-tcp/001
@@ -0,0 +1,55 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0+
+# Copyright (C) 2021 Hannes Reinecke, SUSE Labs
+#
+# Test nvme over tcp connection
+
+. tests/nvmeof-tcp/rc
+
+DESCRIPTION="Create single TCP connection via localhost"
+QUICK=1
+
+requires() {
+ _nvme_requires
+ _have_modules loop
+ _require_nvme_trtype_is_fabrics
+}
+
+
+test() {
+ local port
+ local genctr
+ local subsys="blktests-subsystem-"
+ local hostid="$(uuidgen)"
+ local hostnqn="nqn.2014-08.org.nvmexpress:uuid:${hostid}"
+ local scratch="/tmp/blktest-ns1.img"
+
+ echo "Running ${TEST_NAME}"
+
+ _setup_nvmet
+
+ truncate -s 512M "${scratch}"
+
+ port="$(_create_nvmet_port "${nvme_trtype}")"
+
+ _create_nvmet_subsystem "${subsys}1" "${scratch}"
+ _add_nvmet_subsys_to_port "${port}" "${subsys}1"
+ _create_nvmet_host "${subsys}1" "${hostnqn}"
+
+ nvme connect -t "${nvme_trtype}" -n "${subsys}1" \
+ -a "${def_traddr}" -s "${def_trsvcid}" \
+ --hostnqn="${hostnqn}" --hostid="${hostid}"
+
+ nvme list-subsys
+
+ nvme disconnect -n "${subsys}1"
+
+ _remove_nvmet_subsystem_from_port "${port}" "${subsys}1"
+ _remove_nvmet_subsystem "${subsys}1"
+
+ _remove_nvmet_port "${port}"
+
+ rm ${scratch}
+
+ echo "Test complete"
+}
diff --git a/tests/nvmeof-tcp/001.out b/tests/nvmeof-tcp/001.out
new file mode 100644
index 0000000..1eae834
--- /dev/null
+++ b/tests/nvmeof-tcp/001.out
@@ -0,0 +1,6 @@
+Running nvmeof-tcp/001
+nvme-subsys0 - NQN=blktests-subsystem-1
+\
+ +- nvme0 tcp traddr=127.0.0.1,trsvcid=4420 live
+NQN:blktests-subsystem-1 disconnected 1 controller(s)
+Test complete
diff --git a/tests/nvmeof-tcp/rc b/tests/nvmeof-tcp/rc
new file mode 100644
index 0000000..9ae0899
--- /dev/null
+++ b/tests/nvmeof-tcp/rc
@@ -0,0 +1,347 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0+
+# Copyright (C) 2018 Johannes Thumshirn
+#
+# Test specific to NVMe devices
+
+. common/rc
+
+def_traddr="127.0.0.1"
+def_adrfam="ipv4"
+def_trsvcid="4420"
+nvme_trtype=${nvme_trtype:-"tcp"}
+
+_nvme_requires() {
+ _have_program nvme
+ case ${nvme_trtype} in
+ loop)
+ _have_modules nvmet nvme-core nvme-loop
+ _have_configfs
+ ;;
+ pci)
+ _have_modules nvme nvme-core
+ ;;
+ tcp)
+ _have_modules nvmet nvme-core nvme-tcp nvmet-tcp
+ _have_configfs
+ ;;
+ rdma)
+ _have_modules nvmet nvme-core nvme-rdma nvmet-rdma
+ _have_configfs
+ _have_program rdma
+ _have_modules rdma_rxe || _have_modules siw
+ ;;
+ *)
+ SKIP_REASON="unsupported nvme_trtype=${nvme_trtype}"
+ return 1
+ esac
+ return 0
+}
+
+group_requires() {
+ _have_root
+}
+
+group_device_requires() {
+ _require_test_dev_is_nvme
+}
+
+NVMET_CFS="/sys/kernel/config/nvmet/"
+
+_require_test_dev_is_nvme() {
+ if ! readlink -f "$TEST_DEV_SYSFS/device" | grep -q nvme; then
+ SKIP_REASON="$TEST_DEV is not a NVMe device"
+ return 1
+ fi
+ return 0
+}
+
+_require_nvme_trtype_is_loop() {
+ if [[ "${nvme_trtype}" != "loop" ]]; then
+ SKIP_REASON="nvme_trtype=${nvme_trtype} is not supported in this test"
+ return 1
+ fi
+ return 0
+}
+
+_require_nvme_trtype_is_fabrics() {
+ if [[ "${nvme_trtype}" == "pci" ]]; then
+ SKIP_REASON="nvme_trtype=${nvme_trtype} is not supported in this test"
+ return 1
+ fi
+ return 0
+}
+
+_test_dev_nvme_ctrl() {
+ echo "/dev/char/$(cat "${TEST_DEV_SYSFS}/device/dev")"
+}
+
+_test_dev_nvme_nsid() {
+ cat "${TEST_DEV_SYSFS}/nsid"
+}
+
+_cleanup_nvmet() {
+ local dev
+ local port
+ local subsys
+ local transport
+ local name
+
+ if [[ ! -d "${NVMET_CFS}" ]]; then
+ return 0
+ fi
+
+ # Don't let successive Ctrl-Cs interrupt the cleanup processes
+ trap '' SIGINT
+
+ shopt -s nullglob
+
+ for dev in /sys/class/nvme/nvme*; do
+ dev="$(basename "$dev")"
+ transport="$(cat "/sys/class/nvme/${dev}/transport")"
+ if [[ "$transport" == "${nvme_trtype}" ]]; then
+ echo "WARNING: Test did not clean up ${nvme_trtype} device: ${dev}"
+ _nvme_disconnect_ctrl "${dev}"
+ fi
+ done
+
+ for port in "${NVMET_CFS}"/ports/*; do
+ name=$(basename "${port}")
+ echo "WARNING: Test did not clean up port: ${name}"
+ rm -f "${port}"/subsystems/*
+ rmdir "${port}"
+ done
+
+ for subsys in "${NVMET_CFS}"/subsystems/*; do
+ name=$(basename "${subsys}")
+ echo "WARNING: Test did not clean up subsystem: ${name}"
+ for ns in "${subsys}"/namespaces/*; do
+ rmdir "${ns}"
+ done
+ rmdir "${subsys}"
+ done
+
+ shopt -u nullglob
+ trap SIGINT
+
+ modprobe -r nvme-"${nvme_trtype}" 2>/dev/null
+ if [[ "${nvme_trtype}" != "loop" ]]; then
+ modprobe -r nvmet-"${nvme_trtype}" 2>/dev/null
+ fi
+ modprobe -r nvmet 2>/dev/null
+}
+
+_setup_nvmet() {
+ _register_test_cleanup _cleanup_nvmet
+ modprobe nvmet
+ if [[ "${nvme_trtype}" != "loop" ]]; then
+ modprobe nvmet-"${nvme_trtype}"
+ fi
+ modprobe nvme-"${nvme_trtype}"
+}
+
+_nvme_disconnect_ctrl() {
+ local ctrl="$1"
+
+ nvme disconnect -d "${ctrl}"
+}
+
+_nvme_disconnect_subsys() {
+ local subsysnqn="$1"
+
+ nvme disconnect -n "${subsysnqn}"
+}
+
+_nvme_connect_subsys() {
+ local trtype="$1"
+ local subsysnqn="$2"
+ local traddr="${3:-$def_traddr}"
+ local trsvcid="${4:-$def_trsvcid}"
+
+ ARGS=(-t "${trtype}" -n "${subsysnqn}")
+ if [[ "${trtype}" != "loop" ]]; then
+ ARGS+=(-a "${traddr}" -s "${trsvcid}")
+ fi
+ nvme connect "${ARGS[@]}"
+}
+
+_nvme_discover() {
+ local trtype="$1"
+ local traddr="${2:-$def_traddr}"
+ local trsvcid="${3:-$def_trsvcid}"
+
+ ARGS=(-t "${trtype}")
+ if [[ "${trtype}" != "loop" ]]; then
+ ARGS+=(-a "${traddr}" -s "${trsvcid}")
+ fi
+ nvme discover "${ARGS[@]}"
+}
+
+_create_nvmet_port() {
+ local trtype="$1"
+ local traddr="${2:-$def_traddr}"
+ local adrfam="${3:-$def_adrfam}"
+ local trsvcid="${4:-$def_trsvcid}"
+
+ local port
+ for ((port = 0; ; port++)); do
+ if [[ ! -e "${NVMET_CFS}/ports/${port}" ]]; then
+ break
+ fi
+ done
+
+ mkdir "${NVMET_CFS}/ports/${port}"
+ echo "${trtype}" > "${NVMET_CFS}/ports/${port}/addr_trtype"
+ echo "${traddr}" > "${NVMET_CFS}/ports/${port}/addr_traddr"
+ echo "${adrfam}" > "${NVMET_CFS}/ports/${port}/addr_adrfam"
+ echo "${trsvcid}" > "${NVMET_CFS}/ports/${port}/addr_trsvcid"
+
+ echo "${port}"
+}
+
+_remove_nvmet_port() {
+ local port="$1"
+ rmdir "${NVMET_CFS}/ports/${port}"
+}
+
+_create_nvmet_ns() {
+ local nvmet_subsystem="$1"
+ local nsid="$2"
+ local blkdev="$3"
+ local uuid="00000000-0000-0000-0000-000000000000"
+ local subsys_path="${NVMET_CFS}/subsystems/${nvmet_subsystem}"
+ local ns_path="${subsys_path}/namespaces/${nsid}"
+
+ if [[ $# -eq 4 ]]; then
+ uuid="$4"
+ fi
+
+ mkdir "${ns_path}"
+ printf "%s" "${blkdev}" > "${ns_path}/device_path"
+ printf "%s" "${uuid}" > "${ns_path}/device_uuid"
+ printf 1 > "${ns_path}/enable"
+}
+
+_create_nvmet_subsystem() {
+ local nvmet_subsystem="$1"
+ local blkdev="$2"
+ local uuid=$3
+ local cfs_path="${NVMET_CFS}/subsystems/${nvmet_subsystem}"
+
+ mkdir -p "${cfs_path}"
+ echo 1 > "${cfs_path}/attr_allow_any_host"
+ _create_nvmet_ns "${nvmet_subsystem}" "1" "${blkdev}" "${uuid}"
+}
+
+_create_nvmet_host() {
+ local nvmet_subsystem="$1"
+ local nvmet_hostnqn="$2"
+ local nvmet_hostkey="$3"
+ local cfs_path="${NVMET_CFS}/subsystems/${nvmet_subsystem}"
+
+ mkdir "${NVMET_CFS}/hosts/${nvmet_hostnqn}"
+ if [ "$nvmet_hostkey" ] ; then
+ echo "${nvmet_hostkey}" > \
+ "${NVMET_CFS}/hosts/${nvmet_hostnqn}/dhchap_key"
+ fi
+ echo 0 > "${cfs_path}/attr_allow_any_host"
+ ln -s "${NVMET_CFS}/hosts/${nvmet_hostnqn}" \
+ "${cfs_path}/allowed_hosts/${nvmet_hostnqn}"
+}
+
+_set_nvmet_hostkey() {
+ local nvmet_hostnqn="$1"
+ local nvmet_hostkey="$2"
+ local cfs_path="${NVMET_CFS}/hosts/${nvmet_hostnqn}"
+
+ echo "${nvmet_hostkey}" > \
+ "${cfs_path}/dhchap_key"
+}
+
+_set_nvmet_ctrlkey() {
+ local nvmet_hostnqn="$1"
+ local nvmet_ctrlkey="$2"
+ local cfs_path="${NVMET_CFS}/hosts/${nvmet_hostnqn}"
+
+ echo "${nvmet_ctrlkey}" > \
+ "${cfs_path}/dhchap_ctrl_key"
+}
+
+_set_nvmet_hash() {
+ local nvmet_hostnqn="$1"
+ local nvmet_hash="$2"
+ local cfs_path="${NVMET_CFS}/hosts/${nvmet_hostnqn}"
+
+ echo "${nvmet_hash}" > \
+ "${cfs_path}/dhchap_hash"
+}
+
+_set_nvmet_dhgroup() {
+ local nvmet_hostnqn="$1"
+ local nvmet_dhgroup="$2"
+ local cfs_path="${NVMET_CFS}/hosts/${nvmet_hostnqn}"
+
+ echo "${nvmet_dhgroup}" > \
+ "${cfs_path}/dhchap_dhgroup"
+}
+
+_remove_nvmet_ns() {
+ local nvmet_subsystem="$1"
+ local nsid=$2
+ local subsys_path="${NVMET_CFS}/subsystems/${nvmet_subsystem}"
+ local nvmet_ns_path="${subsys_path}/namespaces/${nsid}"
+
+ echo 0 > "${nvmet_ns_path}/enable"
+ rmdir "${nvmet_ns_path}"
+}
+
+_remove_nvmet_subsystem() {
+ local nvmet_subsystem="$1"
+ local subsys_path="${NVMET_CFS}/subsystems/${nvmet_subsystem}"
+
+ _remove_nvmet_ns "${nvmet_subsystem}" "1"
+ rm "${subsys_path}"/allowed_hosts/*
+ rmdir "${subsys_path}"
+}
+
+_remove_nvmet_host() {
+ local nvmet_host="$1"
+ local host_path="${NVMET_CFS}/hosts/${nvmet_host}"
+
+ rmdir "${host_path}"
+}
+
+_add_nvmet_subsys_to_port() {
+ local port="$1"
+ local nvmet_subsystem="$2"
+
+ ln -s "${NVMET_CFS}/subsystems/${nvmet_subsystem}" \
+ "${NVMET_CFS}/ports/${port}/subsystems/${nvmet_subsystem}"
+}
+
+_remove_nvmet_subsystem_from_port() {
+ local port="$1"
+ local nvmet_subsystem="$2"
+
+ rm "${NVMET_CFS}/ports/${port}/subsystems/${nvmet_subsystem}"
+}
+
+_find_nvme_dev() {
+ local subsys=$1
+ local subsysnqn
+ local dev
+ for dev in /sys/class/nvme/nvme*; do
+ dev="$(basename "$dev")"
+ subsysnqn="$(cat "/sys/class/nvme/${dev}/subsysnqn")"
+ if [[ "$subsysnqn" == "$subsys" ]]; then
+ echo "$dev"
+ for ((i = 0; i < 10; i++)); do
+ if [[ -e /sys/block/$dev/uuid &&
+ -e /sys/block/$dev/wwid ]]; then
+ return
+ fi
+ sleep .1
+ done
+ fi
+ done
+}
--
2.26.2
More information about the Linux-nvme
mailing list