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" 12bpf_sh="$rootdir/scripts/bpftrace.sh" 13 14bdevperf_rpc_sock=/var/tmp/bdevperf.sock 15 16# NQN prefix to use for subsystem NQNs 17NQN=nqn.2016-06.io.spdk:cnode1 18 19nvmftestinit 20 21nvmfappstart -m 0x3 22nvmfapp_pid=$! 23 24$rpc_py nvmf_create_transport $NVMF_TRANSPORT_OPTS -u 8192 25$rpc_py bdev_malloc_create $MALLOC_BDEV_SIZE $MALLOC_BLOCK_SIZE -b Malloc0 26# Set -r to enable ANA reporting feature 27$rpc_py nvmf_create_subsystem $NQN -a -s SPDK00000000000001 -r -m 2 28$rpc_py nvmf_subsystem_add_ns $NQN Malloc0 29$rpc_py nvmf_subsystem_add_listener $NQN -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP -s $NVMF_PORT 30$rpc_py nvmf_subsystem_add_listener $NQN -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP -s $NVMF_SECOND_PORT 31 32$rootdir/test/bdev/bdevperf/bdevperf -m 0x4 -z -r $bdevperf_rpc_sock -q 128 -o 4096 -w verify -t 90 &> $testdir/try.txt & 33bdevperf_pid=$! 34 35trap 'process_shm --id $NVMF_APP_SHM_ID; rm -f $testdir/try.txt; killprocess $bdevperf_pid; nvmftestfini; exit 1' SIGINT SIGTERM EXIT 36waitforlisten $bdevperf_pid $bdevperf_rpc_sock 37 38# Create a controller and set multipath behavior 39# bdev_retry_count is set to -1 means infinite reconnects 40$rpc_py -s $bdevperf_rpc_sock bdev_nvme_set_options -r -1 41# -l -1 ctrlr_loss_timeout_sec -1 means infinite reconnects 42# -o 10 reconnect_delay_sec time to delay a reconnect retry is limited to 10 sec 43$rpc_py -s $bdevperf_rpc_sock bdev_nvme_attach_controller -b Nvme0 -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP -s $NVMF_PORT -f ipv4 -n $NQN -l -1 -o 10 44$rpc_py -s $bdevperf_rpc_sock bdev_nvme_attach_controller -b Nvme0 -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP -s $NVMF_SECOND_PORT -f ipv4 -n $NQN -x multipath -l -1 -o 10 45 46function set_ANA_state() { 47 $rpc_py nvmf_subsystem_listener_set_ana_state $NQN -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP -s $NVMF_PORT -n $1 48 $rpc_py nvmf_subsystem_listener_set_ana_state $NQN -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP -s $NVMF_SECOND_PORT -n $2 49} 50 51# check for io on the expected ANA state port 52function confirm_io_on_port() { 53 $bpf_sh $nvmfapp_pid $rootdir/scripts/bpf/nvmf_path.bt &> $testdir/trace.txt & 54 dtrace_pid=$! 55 sleep 6 56 active_port=$($rpc_py nvmf_subsystem_get_listeners $NQN | jq -r '.[] | select (.ana_states[0].ana_state=="'$1'") | .address.trsvcid') 57 cat $testdir/trace.txt 58 port=$(cut < $testdir/trace.txt -d ']' -f1 | awk '$1=="@path['$NVMF_FIRST_TARGET_IP'," {print $2}' | sed -n '1p') 59 [[ "$active_port" == "$port" ]] 60 [[ "$port" == "$2" ]] 61 kill $dtrace_pid 62 rm -f $testdir/trace.txt 63} 64 65$rootdir/test/bdev/bdevperf/bdevperf.py -t 120 -s $bdevperf_rpc_sock perform_tests & 66rpc_pid=$! 67 68sleep 1 69 70# Set ANA state to each listener 71set_ANA_state non_optimized optimized 72# Check the IO on expected port with ANA state set 73confirm_io_on_port "optimized" $NVMF_SECOND_PORT 74 75# Check traffic paths with different ANA states 76set_ANA_state non_optimized inaccessible 77confirm_io_on_port "non_optimized" $NVMF_PORT 78 79set_ANA_state inaccessible optimized 80confirm_io_on_port "optimized" $NVMF_SECOND_PORT 81 82# Not expecting the io on any port 83set_ANA_state inaccessible inaccessible 84confirm_io_on_port "" "" 85 86set_ANA_state non_optimized optimized 87confirm_io_on_port "optimized" $NVMF_SECOND_PORT 88 89# Remove listener to monitor multipath function 90$rpc_py nvmf_subsystem_remove_listener $NQN -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP -s $NVMF_SECOND_PORT 91sleep 1 92 93# Expect IO on alternate path 94confirm_io_on_port "non_optimized" $NVMF_PORT 95 96# Add listener back with optimized state, traffic should switch to optimized port 97$rpc_py nvmf_subsystem_add_listener $NQN -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP -s $NVMF_SECOND_PORT 98$rpc_py nvmf_subsystem_listener_set_ana_state $NQN -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP -s $NVMF_SECOND_PORT -n optimized 99 100# wait for the io to switch to second port 101sleep 2 102confirm_io_on_port "optimized" $NVMF_SECOND_PORT 103 104wait $rpc_pid 105cat $testdir/try.txt 106 107killprocess $bdevperf_pid 108 109$rpc_py nvmf_delete_subsystem $NQN 110 111trap - SIGINT SIGTERM EXIT 112 113rm -f $testdir/try.txt 114nvmftestfini 115