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