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 11function starttarget() { 12 nvmftestinit 13 14 # Start the target 15 nvmfappstart -m 0x1E 16 17 $rpc_py nvmf_create_transport $NVMF_TRANSPORT_OPTS -u 8192 18 19 num_subsystems=({1..10}) 20 21 timing_enter create_subsystems 22 # Create subsystems 23 rm -rf $testdir/rpcs.txt 24 for i in "${num_subsystems[@]}"; do 25 cat <<- EOL >> $testdir/rpcs.txt 26 bdev_malloc_create $MALLOC_BDEV_SIZE $MALLOC_BLOCK_SIZE -b Malloc$i 27 nvmf_create_subsystem nqn.2016-06.io.spdk:cnode$i -a -s SPDK$i 28 nvmf_subsystem_add_ns nqn.2016-06.io.spdk:cnode$i Malloc$i 29 nvmf_subsystem_add_listener nqn.2016-06.io.spdk:cnode$i -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP -s $NVMF_PORT 30 EOL 31 done 32 $rpc_py < $testdir/rpcs.txt 33 timing_exit create_subsystems 34 35} 36 37function stoptarget() { 38 rm -f ./local-job0-0-verify.state 39 rm -rf $testdir/bdevperf.conf 40 rm -rf $testdir/rpcs.txt 41 42 nvmftestfini 43} 44 45function waitforio() { 46 # $1 = RPC socket 47 if [ -z "$1" ]; then 48 exit 1 49 fi 50 # $2 = bdev name 51 if [ -z "$2" ]; then 52 exit 1 53 fi 54 local ret=1 55 local i 56 for ((i = 10; i != 0; i--)); do 57 read_io_count=$($rpc_py -s $1 bdev_get_iostat -b $2 | jq -r '.bdevs[0].num_read_ops') 58 # A few I/O will happen during initial examine. So wait until at least 100 I/O 59 # have completed to know that bdevperf is really generating the I/O. 60 if [ $read_io_count -ge 100 ]; then 61 ret=0 62 break 63 fi 64 sleep 0.25 65 done 66 return $ret 67} 68 69# Test 1: Kill the initiator unexpectedly with no I/O outstanding 70function nvmf_shutdown_tc1() { 71 starttarget 72 73 # Run bdev_svc, which connects but does not issue I/O 74 $rootdir/test/app/bdev_svc/bdev_svc -m 0x1 -i 1 -r /var/tmp/bdevperf.sock --json <(gen_nvmf_target_json "${num_subsystems[@]}") & 75 perfpid=$! 76 waitforlisten $perfpid /var/tmp/bdevperf.sock 77 $rpc_py -s /var/tmp/bdevperf.sock framework_wait_init 78 79 # Kill bdev_svc 80 kill -9 $perfpid || true 81 rm -f /var/run/spdk_bdev1 82 83 # Verify the target stays up 84 sleep 1 85 kill -0 $nvmfpid 86 87 # Connect with bdevperf and confirm it works 88 $rootdir/test/bdev/bdevperf/bdevperf -r /var/tmp/bdevperf.sock --json <(gen_nvmf_target_json "${num_subsystems[@]}") -q 64 -o 65536 -w verify -t 1 89 90 stoptarget 91} 92 93# Test 2: Kill initiator unexpectedly with I/O outstanding 94function nvmf_shutdown_tc2() { 95 starttarget 96 97 # Run bdevperf 98 $rootdir/test/bdev/bdevperf/bdevperf -r /var/tmp/bdevperf.sock --json <(gen_nvmf_target_json "${num_subsystems[@]}") -q 64 -o 65536 -w verify -t 10 & 99 perfpid=$! 100 waitforlisten $perfpid /var/tmp/bdevperf.sock 101 $rpc_py -s /var/tmp/bdevperf.sock framework_wait_init 102 103 waitforio /var/tmp/bdevperf.sock Nvme1n1 104 105 # Kill bdevperf half way through 106 killprocess $perfpid 107 108 # Verify the target stays up 109 sleep 1 110 kill -0 $nvmfpid 111 112 stoptarget 113} 114 115# Test 3: Kill the target unexpectedly with I/O outstanding 116function nvmf_shutdown_tc3() { 117 starttarget 118 119 # Run bdevperf 120 $rootdir/test/bdev/bdevperf/bdevperf -r /var/tmp/bdevperf.sock --json <(gen_nvmf_target_json "${num_subsystems[@]}") -q 64 -o 65536 -w verify -t 10 & 121 perfpid=$! 122 waitforlisten $perfpid /var/tmp/bdevperf.sock 123 $rpc_py -s /var/tmp/bdevperf.sock framework_wait_init 124 125 # Expand the trap to clean up bdevperf if something goes wrong 126 trap 'process_shm --id $NVMF_APP_SHM_ID; kill -9 $perfpid || true; nvmftestfini; exit 1' SIGINT SIGTERM EXIT 127 128 waitforio /var/tmp/bdevperf.sock Nvme1n1 129 130 # Kill the target half way through 131 killprocess $nvmfpid 132 nvmfpid= 133 134 # Verify bdevperf exits successfully 135 sleep 1 136 # TODO: Right now the NVMe-oF initiator will not correctly detect broken connections 137 # and so it will never shut down. Just kill it. 138 kill -9 $perfpid || true 139 140 stoptarget 141} 142 143run_test "nvmf_shutdown_tc1" nvmf_shutdown_tc1 144run_test "nvmf_shutdown_tc2" nvmf_shutdown_tc2 145run_test "nvmf_shutdown_tc3" nvmf_shutdown_tc3 146 147trap - SIGINT SIGTERM EXIT 148