1#!/usr/bin/env bash 2 3testdir=$(readlink -f $(dirname $0)) 4rootdir=$(readlink -f $testdir/../../..) 5source $rootdir/test/common/autotest_common.sh 6source $rootdir/test/nvmf/common.sh 7 8MALLOC_BDEV_SIZE=64 9MALLOC_BLOCK_SIZE=512 10 11rpc_py="$rootdir/scripts/rpc.py" 12 13function check_ana_state() { 14 local subsys_id=$1 15 local ctrl_id=$2 16 local ana_state=$3 17 # Very rarely a connection is lost and Linux NVMe host tries reconnecting 18 # after 10 seconds delay. For this case, set a sufficiently long timeout. 19 # Linux NVMe host usually recognizes the new ANA state within 2 seconds. 20 local timeout=20 21 22 while [ $(cat /sys/block/nvme"$subsys_id"c"$ctrl_id"n1/ana_state) != "$ana_state" ]; do 23 sleep 1 24 if ((timeout-- == 0)); then 25 echo "timeout before ANA state (nvme$subsys_id c$ctrl_id) becomes $ana_state" 26 return 1 27 fi 28 done 29} 30 31nvmftestinit 32 33if [ -z $NVMF_SECOND_TARGET_IP ]; then 34 echo "only one NIC for nvmf test" 35 nvmftestfini 36 exit 0 37fi 38 39if [ "$TEST_TRANSPORT" != "tcp" ]; then 40 echo "run this test only with TCP transport for now" 41 nvmftestfini 42 exit 0 43fi 44 45nvmfappstart -m 0xF 46 47$rpc_py nvmf_create_transport $NVMF_TRANSPORT_OPTS -u 8192 48 49$rpc_py bdev_malloc_create $MALLOC_BDEV_SIZE $MALLOC_BLOCK_SIZE -b Malloc0 50$rpc_py nvmf_create_subsystem nqn.2016-06.io.spdk:cnode1 -a -s SPDK00000000000001 -r 51$rpc_py nvmf_subsystem_add_ns nqn.2016-06.io.spdk:cnode1 Malloc0 52$rpc_py nvmf_subsystem_add_listener nqn.2016-06.io.spdk:cnode1 -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP -s $NVMF_PORT 53$rpc_py nvmf_subsystem_add_listener nqn.2016-06.io.spdk:cnode1 -t $TEST_TRANSPORT -a $NVMF_SECOND_TARGET_IP -s $NVMF_PORT 54 55nvme connect -t $TEST_TRANSPORT -n "nqn.2016-06.io.spdk:cnode1" -a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT" -g -G 56nvme connect -t $TEST_TRANSPORT -n "nqn.2016-06.io.spdk:cnode1" -a "$NVMF_SECOND_TARGET_IP" -s "$NVMF_PORT" -g -G 57 58waitforserial "$NVMF_SERIAL" 59 60# We assume only a single subsystem. 61subsys_id=$(nvme list-subsys | sed -n 's/nqn.2016-06.io.spdk:cnode1//p' | sed 's/[^0-9]*//g') 62ctrl1_id=$(nvme list-subsys | sed -n "s/traddr=$NVMF_FIRST_TARGET_IP trsvcid=$NVMF_PORT//p" | sed 's/[^0-9]*//g') 63ctrl2_id=$(nvme list-subsys | sed -n "s/traddr=$NVMF_SECOND_TARGET_IP trsvcid=$NVMF_PORT//p" | sed 's/[^0-9]*//g') 64 65check_ana_state "$subsys_id" "$ctrl1_id" "optimized" 66check_ana_state "$subsys_id" "$ctrl2_id" "optimized" 67 68# Set IO policy to numa 69echo numa > /sys/class/nvme-subsystem/nvme-subsys$subsys_id/iopolicy 70 71$rootdir/scripts/fio-wrapper -p nvmf -i 4096 -d 128 -t randrw -r 6 -v & 72fio_pid=$! 73 74sleep 1 75 76$rpc_py nvmf_subsystem_listener_set_ana_state nqn.2016-06.io.spdk:cnode1 -t $TEST_TRANSPORT -a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT" -n inaccessible 77$rpc_py nvmf_subsystem_listener_set_ana_state nqn.2016-06.io.spdk:cnode1 -t $TEST_TRANSPORT -a "$NVMF_SECOND_TARGET_IP" -s "$NVMF_PORT" -n non_optimized 78 79check_ana_state "$subsys_id" "$ctrl1_id" "inaccessible" 80check_ana_state "$subsys_id" "$ctrl2_id" "non-optimized" 81 82$rpc_py nvmf_subsystem_listener_set_ana_state nqn.2016-06.io.spdk:cnode1 -t $TEST_TRANSPORT -a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT" -n non_optimized 83$rpc_py nvmf_subsystem_listener_set_ana_state nqn.2016-06.io.spdk:cnode1 -t $TEST_TRANSPORT -a "$NVMF_SECOND_TARGET_IP" -s "$NVMF_PORT" -n inaccessible 84 85check_ana_state "$subsys_id" "$ctrl1_id" "non-optimized" 86check_ana_state "$subsys_id" "$ctrl2_id" "inaccessible" 87 88wait $fio_pid 89 90$rpc_py nvmf_subsystem_listener_set_ana_state nqn.2016-06.io.spdk:cnode1 -t $TEST_TRANSPORT -a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT" -n optimized 91$rpc_py nvmf_subsystem_listener_set_ana_state nqn.2016-06.io.spdk:cnode1 -t $TEST_TRANSPORT -a "$NVMF_SECOND_TARGET_IP" -s "$NVMF_PORT" -n optimized 92 93check_ana_state "$subsys_id" "$ctrl1_id" "optimized" 94check_ana_state "$subsys_id" "$ctrl2_id" "optimized" 95 96# Set IO policy to round-robin 97echo round-robin > /sys/class/nvme-subsystem/nvme-subsys$subsys_id/iopolicy 98 99$rootdir/scripts/fio-wrapper -p nvmf -i 4096 -d 128 -t randrw -r 6 -v & 100fio_pid=$! 101 102sleep 1 103 104$rpc_py nvmf_subsystem_listener_set_ana_state nqn.2016-06.io.spdk:cnode1 -t $TEST_TRANSPORT -a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT" -n inaccessible 105$rpc_py nvmf_subsystem_listener_set_ana_state nqn.2016-06.io.spdk:cnode1 -t $TEST_TRANSPORT -a "$NVMF_SECOND_TARGET_IP" -s "$NVMF_PORT" -n non_optimized 106 107check_ana_state "$subsys_id" "$ctrl1_id" "inaccessible" 108check_ana_state "$subsys_id" "$ctrl2_id" "non-optimized" 109 110$rpc_py nvmf_subsystem_listener_set_ana_state nqn.2016-06.io.spdk:cnode1 -t $TEST_TRANSPORT -a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT" -n non_optimized 111$rpc_py nvmf_subsystem_listener_set_ana_state nqn.2016-06.io.spdk:cnode1 -t $TEST_TRANSPORT -a "$NVMF_SECOND_TARGET_IP" -s "$NVMF_PORT" -n inaccessible 112 113check_ana_state "$subsys_id" "$ctrl1_id" "non-optimized" 114check_ana_state "$subsys_id" "$ctrl2_id" "inaccessible" 115 116wait $fio_pid 117 118nvme disconnect -n "nqn.2016-06.io.spdk:cnode1" || true 119waitforserial_disconnect "$NVMF_SERIAL" 120 121$rpc_py nvmf_delete_subsystem nqn.2016-06.io.spdk:cnode1 122 123rm -f ./local-job0-0-verify.state 124rm -f ./local-job1-1-verify.state 125 126trap - SIGINT SIGTERM EXIT 127 128nvmftestfini 129