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