1#!/usr/bin/env bash 2# SPDX-License-Identifier: BSD-3-Clause 3# All rights reserved. 4 5testdir=$(readlink -f $(dirname $0)) 6rootdir=$(readlink -f $testdir/../../..) 7source $rootdir/test/common/autotest_common.sh 8source $rootdir/test/nvmf/common.sh 9 10rpc_py="$rootdir/scripts/rpc.py" 11hostsock="/var/tmp/host.sock" 12loops=5 13ns1uuid=$(uuidgen) 14ns2uuid=$(uuidgen) 15 16SUBSYSNQN="nqn.2016-06.io.spdk:cnode1" 17HOSTNQN1="nqn.2016-06.io.spdk:host1" 18HOSTNQN2="nqn.2016-06.io.spdk:host2" 19HOSTID=$(uuidgen) 20 21function connect() { 22 nvme connect -t $TEST_TRANSPORT -n $SUBSYSNQN -q $HOSTNQN1 -I $HOSTID \ 23 -a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT" -i 4 24 waitforserial "$NVMF_SERIAL" $1 25 ctrl_id=$(nvme list-subsys -o json \ 26 | jq -r '.[].Subsystems[] | select(.NQN=='\"$SUBSYSNQN\"') | .Paths[0].Name') 27 if [[ -z "$ctrl_id" ]]; then 28 # The filter returned empty, so dump the raw JSON contents so we 29 # can try to debug why - whether the connect actually failed 30 # or we just aren't filtering the JSON correctly. 31 # We ran into this with issue #3337, which is now resolved, but 32 # leave this here just in case this pops up again in the future. 33 nvme list-subsys -o json 34 fi 35} 36 37function disconnect() { 38 nvme disconnect -n $SUBSYSNQN 39} 40 41# $1 == hex nsid 42function ns_is_visible() { 43 nvme list-ns /dev/$ctrl_id | grep "$1" 44 nguid=$(nvme id-ns /dev/$ctrl_id -n $1 -o json | jq -r ".nguid") 45 [[ $nguid != "00000000000000000000000000000000" ]] 46} 47 48hostrpc() { "$rpc_py" -s "$hostsock" "$@"; } 49 50nvmftestinit 51nvmfappstart 52 53$rpc_py nvmf_create_transport $NVMF_TRANSPORT_OPTS -u 8192 54 55MALLOC_BDEV_SIZE=64 56MALLOC_BLOCK_SIZE=512 57 58$rpc_py bdev_malloc_create $MALLOC_BDEV_SIZE $MALLOC_BLOCK_SIZE -b Malloc1 59$rpc_py bdev_malloc_create $MALLOC_BDEV_SIZE $MALLOC_BLOCK_SIZE -b Malloc2 60 61# No masking (all namespaces automatically visible) 62$rpc_py nvmf_create_subsystem $SUBSYSNQN -a -s $NVMF_SERIAL 63$rpc_py nvmf_subsystem_add_ns $SUBSYSNQN Malloc1 -n 1 64$rpc_py nvmf_subsystem_add_listener $SUBSYSNQN -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP -s $NVMF_PORT 65 66# Namespace should be visible 67connect 68ns_is_visible "0x1" 69 70# Add 2nd namespace and check visible 71$rpc_py nvmf_subsystem_add_ns $SUBSYSNQN Malloc2 -n 2 72ns_is_visible "0x1" 73ns_is_visible "0x2" 74 75disconnect 76 77# Remove ns1 and re-add without auto visibility 78# Note: we will leave ns2 with auto-attach for rest of this test 79$rpc_py nvmf_subsystem_remove_ns $SUBSYSNQN 1 80$rpc_py nvmf_subsystem_add_ns $SUBSYSNQN Malloc1 -n 1 --no-auto-visible 81 82# ns1 should be invisible 83connect 1 84NOT ns_is_visible "0x1" 85ns_is_visible "0x2" 86 87# hot attach and check ns1 visible 88$rpc_py nvmf_ns_add_host $SUBSYSNQN 1 $HOSTNQN1 89ns_is_visible "0x1" 90ns_is_visible "0x2" 91 92# hot detach and check ns1 invisible 93$rpc_py nvmf_ns_remove_host $SUBSYSNQN 1 $HOSTNQN1 94NOT ns_is_visible "0x1" 95ns_is_visible "0x2" 96 97disconnect 98 99# cold attach, connect and check ns1 visible 100$rpc_py nvmf_ns_add_host $SUBSYSNQN 1 $HOSTNQN1 101connect 2 102ns_is_visible "0x1" 103ns_is_visible "0x2" 104 105# detach and check ns1 invisible 106$rpc_py nvmf_ns_remove_host $SUBSYSNQN 1 $HOSTNQN1 107NOT ns_is_visible "0x1" 108ns_is_visible "0x2" 109 110# hot detach ns2 should not work, since ns2 is auto-visible 111NOT $rpc_py nvmf_ns_remove_host $SUBSYSNQN 2 $HOSTNQN1 112NOT ns_is_visible "0x1" 113ns_is_visible "0x2" 114disconnect 115 116# check two connections with different NQNs to the same subsystem on the same traddr using bdev_nvme 117"$rootdir/build/bin/spdk_tgt" -r "$hostsock" -m 2 & 118hostpid=$! 119trap 'killprocess $hostpid; nvmftestfini' SIGINT SIGTERM EXIT 120 121waitforlisten "$hostpid" "$hostsock" 122"$rpc_py" nvmf_subsystem_remove_ns "$SUBSYSNQN" 1 123"$rpc_py" nvmf_subsystem_remove_ns "$SUBSYSNQN" 2 124"$rpc_py" nvmf_subsystem_add_ns "$SUBSYSNQN" Malloc1 -n 1 -g $(uuid2nguid "$ns1uuid") -i 125"$rpc_py" nvmf_subsystem_add_ns "$SUBSYSNQN" Malloc2 -n 2 -g $(uuid2nguid "$ns2uuid") -i 126"$rpc_py" nvmf_ns_add_host "$SUBSYSNQN" 1 "$HOSTNQN1" 127"$rpc_py" nvmf_ns_add_host "$SUBSYSNQN" 2 "$HOSTNQN2" 128 129hostrpc bdev_nvme_attach_controller -t "$TEST_TRANSPORT" -a "$NVMF_FIRST_TARGET_IP" -f ipv4 \ 130 -s "$NVMF_PORT" -n "$SUBSYSNQN" -q "$HOSTNQN1" -b nvme0 131hostrpc bdev_nvme_attach_controller -t "$TEST_TRANSPORT" -a "$NVMF_FIRST_TARGET_IP" -f ipv4 \ 132 -s "$NVMF_PORT" -n "$SUBSYSNQN" -q "$HOSTNQN2" -b nvme1 133 134[[ $(hostrpc bdev_get_bdevs | jq -r '.[].name' | sort | xargs) == "nvme0n1 nvme1n2" ]] 135[[ $(hostrpc bdev_get_bdevs -b nvme0n1 | jq -r '.[].uuid') == "$ns1uuid" ]] 136[[ $(hostrpc bdev_get_bdevs -b nvme1n2 | jq -r '.[].uuid') == "$ns2uuid" ]] 137"$rpc_py" nvmf_subsystem_remove_ns "$SUBSYSNQN" 1 138"$rpc_py" nvmf_subsystem_remove_ns "$SUBSYSNQN" 2 139 140# Check that a failed add_ns doesn't leave the ns visible flag set, see issue #3544 141NOT "$rpc_py" nvmf_subsystem_add_ns "$SUBSYSNQN" invalid -n 1 -g $(uuid2nguid "$ns1uuid") 142"$rpc_py" nvmf_subsystem_add_ns "$SUBSYSNQN" Malloc1 -n 1 -g $(uuid2nguid "$ns1uuid") -i 143sleep 2s 144(($(hostrpc bdev_get_bdevs | jq 'length') == 0)) 145 146killprocess $hostpid 147$rpc_py nvmf_delete_subsystem $SUBSYSNQN 148 149trap - SIGINT SIGTERM EXIT 150nvmftestfini 151