xref: /spdk/test/nvmf/target/shutdown.sh (revision 18c8b52afa69f39481ebb75711b2f30b11693f9d)
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