xref: /spdk/test/bdev/blockdev.sh (revision e28e247954152cafc82bd3ec1189b7ba80fe214e)
1#!/usr/bin/env bash
2
3testdir=$(readlink -f $(dirname $0))
4rootdir=$(readlink -f $testdir/../..)
5source $rootdir/test/common/autotest_common.sh
6source $testdir/nbd_common.sh
7
8shopt -s nullglob extglob
9
10rpc_py=rpc_cmd
11conf_file="$testdir/bdev.json"
12nonenclosed_conf_file="$testdir/nonenclosed.json"
13nonarray_conf_file="$testdir/nonarray.json"
14
15# Make sure the configuration is clean
16: > "$conf_file"
17
18function cleanup() {
19	rm -f "$SPDK_TEST_STORAGE/aiofile"
20	rm -f "$SPDK_TEST_STORAGE/spdk-pmem-pool"
21	rm -f "$conf_file"
22
23	if [[ $test_type == rbd ]]; then
24		rbd_cleanup
25	fi
26
27	if [[ $test_type == daos ]]; then
28		daos_cleanup
29	fi
30
31	if [[ "$test_type" = "gpt" ]]; then
32		"$rootdir/scripts/setup.sh" reset
33		if [[ -b $gpt_nvme ]]; then
34			wipefs --all "$gpt_nvme"
35		fi
36	fi
37	if [[ $test_type == xnvme ]]; then
38		"$rootdir/scripts/setup.sh"
39	fi
40}
41
42function start_spdk_tgt() {
43	"$SPDK_BIN_DIR/spdk_tgt" "$env_ctx" &
44	spdk_tgt_pid=$!
45	trap 'killprocess "$spdk_tgt_pid"; exit 1' SIGINT SIGTERM EXIT
46	waitforlisten "$spdk_tgt_pid"
47}
48
49function setup_bdev_conf() {
50	"$rpc_py" <<- RPC
51		bdev_split_create Malloc1 2
52		bdev_split_create -s 4 Malloc2 8
53		bdev_malloc_create -b Malloc0 32 512
54		bdev_malloc_create -b Malloc1 32 512
55		bdev_malloc_create -b Malloc2 32 512
56		bdev_malloc_create -b Malloc3 32 512
57		bdev_malloc_create -b Malloc4 32 512
58		bdev_malloc_create -b Malloc5 32 512
59		bdev_malloc_create -b Malloc6 32 512
60		bdev_malloc_create -b Malloc7 32 512
61		bdev_passthru_create -p TestPT -b Malloc3
62		bdev_raid_create -n raid0 -z 64 -r 0 -b "Malloc4 Malloc5"
63		bdev_raid_create -n concat0 -z 64 -r concat -b "Malloc6 Malloc7"
64		bdev_set_qos_limit --rw_mbytes_per_sec 100 Malloc3
65		bdev_set_qos_limit --rw_ios_per_sec 20000 Malloc0
66	RPC
67	if [[ $(uname -s) != "FreeBSD" ]]; then
68		dd if=/dev/zero of="$SPDK_TEST_STORAGE/aiofile" bs=2048 count=5000
69		"$rpc_py" bdev_aio_create "$SPDK_TEST_STORAGE/aiofile" AIO0 2048
70	fi
71}
72
73function setup_nvme_conf() {
74	local json
75	mapfile -t json < <("$rootdir/scripts/gen_nvme.sh")
76	"$rpc_py" load_subsystem_config -j "'${json[*]}'"
77}
78
79function setup_xnvme_conf() {
80	# TODO: Switch to io_uring_cmd when proper CI support is in place
81	local io_mechanism=io_uring
82	local nvme nvmes
83
84	"$rootdir/scripts/setup.sh" reset
85	get_zoned_devs
86
87	for nvme in /dev/nvme*n*; do
88		[[ -b $nvme && -z ${zoned_devs["${nvme##*/}"]} ]] || continue
89		nvmes+=("bdev_xnvme_create $nvme ${nvme##*/} $io_mechanism")
90	done
91
92	((${#nvmes[@]} > 0))
93	"$rpc_py" < <(printf '%s\n' "${nvmes[@]}")
94}
95
96function setup_gpt_conf() {
97	$rootdir/scripts/setup.sh reset
98	get_zoned_devs
99	# Get nvme devices by following drivers' links towards nvme class
100	local nvme_devs=(/sys/bus/pci/drivers/nvme/*/nvme/nvme*/nvme*n*) nvme_dev
101	gpt_nvme=""
102	# Pick first device which doesn't have any valid partition table
103	for nvme_dev in "${nvme_devs[@]}"; do
104		[[ -z ${zoned_devs["${nvme_dev##*/}"]} ]] || continue
105		dev=/dev/${nvme_dev##*/}
106		if ! pt=$(parted "$dev" -ms print 2>&1); then
107			[[ $pt == *"$dev: unrecognised disk label"* ]] || continue
108			gpt_nvme=$dev
109			break
110		fi
111	done
112	if [[ -n $gpt_nvme ]]; then
113		# Create gpt partition table
114		parted -s "$gpt_nvme" mklabel gpt mkpart SPDK_TEST_first '0%' '50%' mkpart SPDK_TEST_second '50%' '100%'
115		# change the GUID to SPDK GUID value
116		SPDK_GPT_GUID=$(get_spdk_gpt)
117		sgdisk -t "1:$SPDK_GPT_GUID" "$gpt_nvme"
118		sgdisk -t "2:$SPDK_GPT_GUID" "$gpt_nvme"
119		"$rootdir/scripts/setup.sh"
120		"$rpc_py" bdev_get_bdevs
121		setup_nvme_conf
122	else
123		printf 'Did not find any nvme block devices to work with, aborting the test\n' >&2
124		"$rootdir/scripts/setup.sh"
125		return 1
126	fi
127}
128
129function setup_crypto_aesni_conf() {
130	# Malloc0 and Malloc1 use AESNI
131	"$rpc_py" <<- RPC
132		bdev_malloc_create -b Malloc0 16 512
133		bdev_malloc_create -b Malloc1 16 512
134		bdev_crypto_create Malloc0 crypto_ram crypto_aesni_mb 01234567891234560123456789123456
135		bdev_crypto_create Malloc1 crypto_ram2 crypto_aesni_mb 90123456789123459012345678912345
136	RPC
137}
138
139function setup_crypto_qat_conf() {
140	# Malloc0 will use QAT AES_CBC
141	# Malloc1 will use QAT AES_XTS
142	"$rpc_py" <<- RPC
143		bdev_malloc_create -b Malloc0 16 512
144		bdev_malloc_create -b Malloc1 16 512
145		bdev_crypto_create Malloc0 crypto_ram crypto_qat 01234567891234560123456789123456
146		bdev_crypto_create -c AES_XTS -k2 01234567891234560123456789123456 Malloc1 crypto_ram3 crypto_qat 01234567891234560123456789123456
147		bdev_get_bdevs -b Malloc1
148	RPC
149}
150
151function setup_crypto_mlx5_conf() {
152	local key=$1
153	local block_key
154	local tweak_key
155	if [ ${#key} == 96 ]; then
156		# 96 bytes is 64 + 32 - AES_XTS_256 in hexlified format
157		# Copy first 64 chars into the 'key'. This gives 32 in the
158		# binary or 256 bit.
159		block_key=${key:0:64}
160		# Copy the the rest of the key and pass it as the 'key2'.
161		tweak_key=${key:64:32}
162	elif [ ${#key} == 160 ]; then
163		# 160 bytes is 128 + 32 - AES_XTS_512 in hexlified format
164		# Copy first 128 chars into the 'key'. This gives 64 in the
165		# binary or 512 bit.
166		block_key=${key:0:128}
167		# Copy the the rest of the key and pass it as the 'key2'.
168		tweak_key=${key:128:32}
169	else
170		echo "ERROR: Invalid DEK size for MLX5 crypto setup: ${#key}"
171		echo "ERROR: Supported key sizes for MLX5: 96 bytes (AES_XTS_256) and 160 bytes (AES_XTS_512)."
172		return 1
173	fi
174
175	# Malloc0 will use MLX5 AES_XTS
176	"$rpc_py" <<- RPC
177		bdev_malloc_create -b Malloc0 16 512
178		bdev_crypto_create -c AES_XTS -k2 $tweak_key Malloc0 crypto_ram4 mlx5_pci $block_key
179		bdev_get_bdevs -b Malloc0
180	RPC
181}
182
183function setup_pmem_conf() {
184	if hash pmempool; then
185		rm -f "$SPDK_TEST_STORAGE/spdk-pmem-pool"
186		pmempool create blk --size=32M 512 "$SPDK_TEST_STORAGE/spdk-pmem-pool"
187		"$rpc_py" bdev_pmem_create -n Pmem0 "$SPDK_TEST_STORAGE/spdk-pmem-pool"
188	else
189		return 1
190	fi
191}
192
193function setup_rbd_conf() {
194	timing_enter rbd_setup
195	rbd_setup 127.0.0.1
196	timing_exit rbd_setup
197
198	"$rpc_py" bdev_rbd_create -b Ceph0 rbd foo 512
199}
200
201function setup_daos_conf() {
202	local pool=testpool
203	local cont=testcont
204
205	timing_enter daos_setup
206	daos_setup $pool $cont
207	timing_exit daos_setup
208
209	"$rpc_py" bdev_daos_create Daos0 $pool $cont 16 4096
210}
211
212function setup_raid5f_conf() {
213	"$rpc_py" <<- RPC
214		bdev_malloc_create -b Malloc0 32 512
215		bdev_malloc_create -b Malloc1 32 512
216		bdev_malloc_create -b Malloc2 32 512
217		bdev_raid_create -n raid5f -z 2 -r 5f -b "Malloc0 Malloc1 Malloc2"
218	RPC
219}
220
221function bdev_bounds() {
222	$testdir/bdevio/bdevio -w -s $PRE_RESERVED_MEM --json "$conf_file" "$env_ctx" &
223	bdevio_pid=$!
224	trap 'cleanup; killprocess $bdevio_pid; exit 1' SIGINT SIGTERM EXIT
225	echo "Process bdevio pid: $bdevio_pid"
226	waitforlisten $bdevio_pid
227	$testdir/bdevio/tests.py perform_tests
228	killprocess $bdevio_pid
229	trap - SIGINT SIGTERM EXIT
230}
231
232function nbd_function_test() {
233	[[ $(uname -s) == Linux ]] || return 0
234
235	local rpc_server=/var/tmp/spdk-nbd.sock
236	local conf=$1
237	local bdev_all=($2)
238	local bdev_num=${#bdev_all[@]}
239
240	# FIXME: Centos7 in the CI is not shipped with a kernel supporting BLK_DEV_NBD
241	# so don't fail here for now.
242	[[ -e /sys/module/nbd ]] || modprobe -q nbd nbds_max=$bdev_num || return 0
243
244	local nbd_all=(/dev/nbd+([0-9]))
245	bdev_num=$((${#nbd_all[@]} < bdev_num ? ${#nbd_all[@]} : bdev_num))
246
247	local nbd_list=(${nbd_all[@]::bdev_num})
248	local bdev_list=(${bdev_all[@]::bdev_num})
249
250	$rootdir/test/app/bdev_svc/bdev_svc -r $rpc_server -i 0 --json "$conf" "$env_ctx" &
251	nbd_pid=$!
252	trap 'cleanup; killprocess $nbd_pid' SIGINT SIGTERM EXIT
253	waitforlisten $nbd_pid $rpc_server
254
255	nbd_rpc_start_stop_verify $rpc_server "${bdev_list[*]}"
256	nbd_rpc_data_verify $rpc_server "${bdev_list[*]}" "${nbd_list[*]}"
257	nbd_with_lvol_verify $rpc_server "${nbd_list[*]}"
258
259	killprocess $nbd_pid
260	trap - SIGINT SIGTERM EXIT
261}
262
263function fio_test_suite() {
264	local env_context
265
266	# Make sure that state files and anything else produced by fio test will
267	# stay at the testdir.
268	pushd $testdir
269	trap 'rm -f ./*.state; popd; exit 1' SIGINT SIGTERM EXIT
270
271	# Generate the fio config file given the list of all unclaimed bdevs
272	env_context=$(echo "$env_ctx" | sed 's/--env-context=//')
273	fio_config_gen $testdir/bdev.fio verify AIO "$env_context"
274	for b in $(echo $bdevs | jq -r '.name'); do
275		echo "[job_$b]" >> $testdir/bdev.fio
276		echo "filename=$b" >> $testdir/bdev.fio
277	done
278
279	local fio_params="--ioengine=spdk_bdev --iodepth=8 --bs=4k --runtime=10 $testdir/bdev.fio \
280			--verify_state_save=0 --spdk_json_conf=$conf_file"
281
282	run_test "bdev_fio_rw_verify" fio_bdev $fio_params --spdk_mem=$PRE_RESERVED_MEM --aux-path=$output_dir
283	rm -f ./*.state
284	rm -f $testdir/bdev.fio
285
286	# Generate the fio config file given the list of all unclaimed bdevs that support unmap
287	fio_config_gen $testdir/bdev.fio trim "" "$env_context"
288	if [ "$(echo $bdevs | jq -r 'select(.supported_io_types.unmap == true) | .name')" != "" ]; then
289		for b in $(echo $bdevs | jq -r 'select(.supported_io_types.unmap == true) | .name'); do
290			echo "[job_$b]" >> $testdir/bdev.fio
291			echo "filename=$b" >> $testdir/bdev.fio
292		done
293	else
294		rm -f $testdir/bdev.fio
295		popd
296		trap - SIGINT SIGTERM EXIT
297		return 0
298	fi
299
300	run_test "bdev_fio_trim" fio_bdev $fio_params --verify_state_save=0 --aux-path=$output_dir
301	rm -f ./*.state
302	rm -f $testdir/bdev.fio
303	popd
304	trap - SIGINT SIGTERM EXIT
305}
306
307function get_io_result() {
308	local limit_type=$1
309	local qos_dev=$2
310	local iostat_result
311	iostat_result=$($rootdir/scripts/iostat.py -d -i 1 -t $QOS_RUN_TIME | grep $qos_dev | tail -1)
312	if [ $limit_type = IOPS ]; then
313		iostat_result=$(awk '{print $2}' <<< $iostat_result)
314	elif [ $limit_type = BANDWIDTH ]; then
315		iostat_result=$(awk '{print $6}' <<< $iostat_result)
316	fi
317
318	echo ${iostat_result/.*/}
319}
320
321function run_qos_test() {
322	local qos_limit=$1
323	local qos_result=0
324
325	qos_result=$(get_io_result $2 $3)
326	if [ $2 = BANDWIDTH ]; then
327		qos_limit=$((qos_limit * 1024))
328	fi
329	lower_limit=$((qos_limit * 9 / 10))
330	upper_limit=$((qos_limit * 11 / 10))
331
332	# QoS realization is related with bytes transferred. It currently has some variation.
333	if [ $qos_result -lt $lower_limit ] || [ $qos_result -gt $upper_limit ]; then
334		echo "Failed to limit the io read rate of NULL bdev by qos"
335		$rpc_py bdev_malloc_delete $QOS_DEV_1
336		$rpc_py bdev_null_delete $QOS_DEV_2
337		killprocess $QOS_PID
338		exit 1
339	fi
340}
341
342function qos_function_test() {
343	local qos_lower_iops_limit=1000
344	local qos_lower_bw_limit=2
345	local io_result=0
346	local iops_limit=0
347	local bw_limit=0
348
349	io_result=$(get_io_result IOPS $QOS_DEV_1)
350	# Set the IOPS limit as one quarter of the measured performance without QoS
351	iops_limit=$(((io_result / 4) / qos_lower_iops_limit * qos_lower_iops_limit))
352	if [ $iops_limit -gt $qos_lower_iops_limit ]; then
353
354		# Run bdevperf with IOPS rate limit on bdev 1
355		$rpc_py bdev_set_qos_limit --rw_ios_per_sec $iops_limit $QOS_DEV_1
356		run_test "bdev_qos_iops" run_qos_test $iops_limit IOPS $QOS_DEV_1
357
358		# Run bdevperf with bandwidth rate limit on bdev 2
359		# Set the bandwidth limit as 1/10 of the measure performance without QoS
360		bw_limit=$(get_io_result BANDWIDTH $QOS_DEV_2)
361		bw_limit=$((bw_limit / 1024 / 10))
362		if [ $bw_limit -lt $qos_lower_bw_limit ]; then
363			bw_limit=$qos_lower_bw_limit
364		fi
365		$rpc_py bdev_set_qos_limit --rw_mbytes_per_sec $bw_limit $QOS_DEV_2
366		run_test "bdev_qos_bw" run_qos_test $bw_limit BANDWIDTH $QOS_DEV_2
367
368		# Run bdevperf with additional read only bandwidth rate limit on bdev 1
369		$rpc_py bdev_set_qos_limit --r_mbytes_per_sec $qos_lower_bw_limit $QOS_DEV_1
370		run_test "bdev_qos_ro_bw" run_qos_test $qos_lower_bw_limit BANDWIDTH $QOS_DEV_1
371	else
372		echo "Actual IOPS without limiting is too low - exit testing"
373	fi
374}
375
376function qos_test_suite() {
377	# Run bdevperf with QoS disabled first
378	"$testdir/bdevperf/bdevperf" -z -m 0x2 -q 256 -o 4096 -w randread -t 60 "$env_ctx" &
379	QOS_PID=$!
380	echo "Process qos testing pid: $QOS_PID"
381	trap 'cleanup; killprocess $QOS_PID; exit 1' SIGINT SIGTERM EXIT
382	waitforlisten $QOS_PID
383
384	$rpc_py bdev_malloc_create -b $QOS_DEV_1 128 512
385	waitforbdev $QOS_DEV_1
386	$rpc_py bdev_null_create $QOS_DEV_2 128 512
387	waitforbdev $QOS_DEV_2
388
389	$rootdir/test/bdev/bdevperf/bdevperf.py perform_tests &
390	qos_function_test
391
392	$rpc_py bdev_malloc_delete $QOS_DEV_1
393	$rpc_py bdev_null_delete $QOS_DEV_2
394	killprocess $QOS_PID
395	trap - SIGINT SIGTERM EXIT
396}
397
398function error_test_suite() {
399	DEV_1="Dev_1"
400	DEV_2="Dev_2"
401	ERR_DEV="EE_Dev_1"
402
403	# Run bdevperf with 1 normal bdev and 1 error bdev, also continue on error
404	"$testdir/bdevperf/bdevperf" -z -m 0x2 -q 16 -o 4096 -w randread -t 5 -f "$env_ctx" &
405	ERR_PID=$!
406	echo "Process error testing pid: $ERR_PID"
407	waitforlisten $ERR_PID
408
409	$rpc_py bdev_malloc_create -b $DEV_1 128 512
410	waitforbdev $DEV_1
411	$rpc_py bdev_error_create $DEV_1
412	$rpc_py bdev_malloc_create -b $DEV_2 128 512
413	waitforbdev $DEV_2
414	$rpc_py bdev_error_inject_error $ERR_DEV 'all' 'failure' -n 5
415
416	$rootdir/test/bdev/bdevperf/bdevperf.py -t 1 perform_tests &
417	sleep 1
418
419	# Bdevperf is expected to be there as the continue on error is set
420	if kill -0 $ERR_PID; then
421		echo "Process is existed as continue on error is set. Pid: $ERR_PID"
422	else
423		echo "Process exited unexpectedly. Pid: $ERR_PID"
424		exit 1
425	fi
426
427	# Delete the error devices
428	$rpc_py bdev_error_delete $ERR_DEV
429	$rpc_py bdev_malloc_delete $DEV_1
430	sleep 5
431	# Expected to exit normally
432	killprocess $ERR_PID
433
434	# Run bdevperf with 1 normal bdev and 1 error bdev, and exit on error
435	"$testdir/bdevperf/bdevperf" -z -m 0x2 -q 16 -o 4096 -w randread -t 5 "$env_ctx" &
436	ERR_PID=$!
437	echo "Process error testing pid: $ERR_PID"
438	waitforlisten $ERR_PID
439
440	$rpc_py bdev_malloc_create -b $DEV_1 128 512
441	waitforbdev $DEV_1
442	$rpc_py bdev_error_create $DEV_1
443	$rpc_py bdev_malloc_create -b $DEV_2 128 512
444	waitforbdev $DEV_2
445	$rpc_py bdev_error_inject_error $ERR_DEV 'all' 'failure' -n 5
446
447	$rootdir/test/bdev/bdevperf/bdevperf.py -t 1 perform_tests &
448	NOT wait $ERR_PID
449}
450
451function qd_sampling_function_test() {
452	local bdev_name=$1
453	local sampling_period=10
454	local iostats
455
456	$rpc_py bdev_set_qd_sampling_period $bdev_name $sampling_period
457
458	iostats=$($rpc_py bdev_get_iostat -b $bdev_name)
459
460	qd_sampling_period=$(jq -r '.bdevs[0].queue_depth_polling_period' <<< "$iostats")
461
462	if [ $qd_sampling_period == null ] || [ $qd_sampling_period -ne $sampling_period ]; then
463		echo "Qeueue depth polling period is not right"
464		$rpc_py bdev_malloc_delete $QD_DEV
465		killprocess $QD_PID
466		exit 1
467	fi
468}
469
470function qd_sampling_test_suite() {
471	QD_DEV="Malloc_QD"
472
473	"$testdir/bdevperf/bdevperf" -z -m 0x3 -q 256 -o 4096 -w randread -t 5 -C "$env_ctx" &
474	QD_PID=$!
475	echo "Process bdev QD sampling period testing pid: $QD_PID"
476	trap 'cleanup; killprocess $QD_PID; exit 1' SIGINT SIGTERM EXIT
477	waitforlisten $QD_PID
478
479	$rpc_py bdev_malloc_create -b $QD_DEV 128 512
480	waitforbdev $QD_DEV
481
482	$rootdir/test/bdev/bdevperf/bdevperf.py perform_tests &
483	sleep 2
484	qd_sampling_function_test $QD_DEV
485
486	$rpc_py bdev_malloc_delete $QD_DEV
487	killprocess $QD_PID
488	trap - SIGINT SIGTERM EXIT
489}
490
491function stat_function_test() {
492	local bdev_name=$1
493	local iostats
494	local io_count1
495	local io_count2
496	local iostats_per_channel
497	local io_count_per_channel1
498	local io_count_per_channel2
499	local io_count_per_channel_all=0
500
501	iostats=$($rpc_py bdev_get_iostat -b $bdev_name)
502	io_count1=$(jq -r '.bdevs[0].num_read_ops' <<< "$iostats")
503
504	iostats_per_channel=$($rpc_py bdev_get_iostat -b $bdev_name -c)
505	io_count_per_channel1=$(jq -r '.channels[0].num_read_ops' <<< "$iostats_per_channel")
506	io_count_per_channel_all=$((io_count_per_channel_all + io_count_per_channel1))
507	io_count_per_channel2=$(jq -r '.channels[1].num_read_ops' <<< "$iostats_per_channel")
508	io_count_per_channel_all=$((io_count_per_channel_all + io_count_per_channel2))
509
510	iostats=$($rpc_py bdev_get_iostat -b $bdev_name)
511	io_count2=$(jq -r '.bdevs[0].num_read_ops' <<< "$iostats")
512
513	# There is little time passed between the three iostats collected. So that
514	# the accumulated statistics from per channel data shall be bigger than the
515	# the first run and smaller than the third run in this short time of period.
516	if [ $io_count_per_channel_all -lt $io_count1 ] || [ $io_count_per_channel_all -gt $io_count2 ]; then
517		echo "Failed to collect the per Core IO statistics"
518		$rpc_py bdev_malloc_delete $STAT_DEV
519		killprocess $STAT_PID
520		exit 1
521	fi
522}
523
524function stat_test_suite() {
525	STAT_DEV="Malloc_STAT"
526
527	# Run bdevperf with 2 cores so as to collect per Core IO statistics
528	"$testdir/bdevperf/bdevperf" -z -m 0x3 -q 256 -o 4096 -w randread -t 10 -C "$env_ctx" &
529	STAT_PID=$!
530	echo "Process Bdev IO statistics testing pid: $STAT_PID"
531	trap 'cleanup; killprocess $STAT_PID; exit 1' SIGINT SIGTERM EXIT
532	waitforlisten $STAT_PID
533
534	$rpc_py bdev_malloc_create -b $STAT_DEV 128 512
535	waitforbdev $STAT_DEV
536
537	$rootdir/test/bdev/bdevperf/bdevperf.py perform_tests &
538	sleep 2
539	stat_function_test $STAT_DEV
540
541	$rpc_py bdev_malloc_delete $STAT_DEV
542	killprocess $STAT_PID
543	trap - SIGINT SIGTERM EXIT
544}
545
546# Inital bdev creation and configuration
547#-----------------------------------------------------
548QOS_DEV_1="Malloc_0"
549QOS_DEV_2="Null_1"
550QOS_RUN_TIME=5
551
552if [ $(uname -s) = Linux ]; then
553	# Test dynamic memory management. All hugepages will be reserved at runtime
554	PRE_RESERVED_MEM=0
555else
556	# Dynamic memory management is not supported on BSD
557	PRE_RESERVED_MEM=2048
558fi
559
560test_type=${1:-bdev}
561crypto_device=$2
562wcs_file=$3
563dek=$4
564env_ctx=""
565if [ -n "$crypto_device" ] && [ -n "$wcs_file" ]; then
566	# We need full path here since fio perf test does 'pushd' to the test dir
567	# and crypto login of fio plugin test can fail.
568	wcs_file=$(readlink -f $wcs_file)
569	if [ -f $wcs_file ]; then
570		env_ctx="--env-context=--allow=$crypto_device,class=crypto,wcs_file=$wcs_file"
571	else
572		echo "ERROR: Credentials file $3 is not found!"
573		exit 1
574	fi
575fi
576start_spdk_tgt
577case "$test_type" in
578	bdev)
579		setup_bdev_conf
580		;;
581	nvme)
582		setup_nvme_conf
583		;;
584	gpt)
585		setup_gpt_conf
586		;;
587	crypto_aesni)
588		setup_crypto_aesni_conf
589		;;
590	crypto_qat)
591		setup_crypto_qat_conf
592		;;
593	crypto_mlx5)
594		setup_crypto_mlx5_conf $dek
595		;;
596	pmem)
597		setup_pmem_conf
598		;;
599	rbd)
600		setup_rbd_conf
601		;;
602	daos)
603		setup_daos_conf
604		;;
605	raid5f)
606		setup_raid5f_conf
607		;;
608	xnvme)
609		setup_xnvme_conf
610		;;
611	*)
612		echo "invalid test name"
613		exit 1
614		;;
615esac
616
617"$rpc_py" bdev_wait_for_examine
618
619# Generate json config and use it throughout all the tests
620cat <<- CONF > "$conf_file"
621	        {"subsystems":[
622	        $("$rpc_py" save_subsystem_config -n bdev)
623	        ]}
624CONF
625
626bdevs=$("$rpc_py" bdev_get_bdevs | jq -r '.[] | select(.claimed == false)')
627bdevs_name=$(echo $bdevs | jq -r '.name')
628bdev_list=($bdevs_name)
629hello_world_bdev=${bdev_list[0]}
630trap - SIGINT SIGTERM EXIT
631killprocess "$spdk_tgt_pid"
632# End bdev configuration
633#-----------------------------------------------------
634
635trap "cleanup" SIGINT SIGTERM EXIT
636
637run_test "bdev_hello_world" $SPDK_EXAMPLE_DIR/hello_bdev --json "$conf_file" -b "$hello_world_bdev" "$env_ctx"
638run_test "bdev_bounds" bdev_bounds "$env_ctx"
639run_test "bdev_nbd" nbd_function_test $conf_file "$bdevs_name" "$env_ctx"
640if [[ $CONFIG_FIO_PLUGIN == y ]]; then
641	if [ "$test_type" = "nvme" ] || [ "$test_type" = "gpt" ]; then
642		# TODO: once we get real multi-ns drives, re-enable this test for NVMe.
643		echo "skipping fio tests on NVMe due to multi-ns failures."
644	else
645		run_test "bdev_fio" fio_test_suite "$env_ctx"
646	fi
647else
648	echo "FIO not available"
649	exit 1
650fi
651
652trap "cleanup" SIGINT SIGTERM EXIT
653
654run_test "bdev_verify" $testdir/bdevperf/bdevperf --json "$conf_file" -q 128 -o 4096 -w verify -t 5 -C -m 0x3 "$env_ctx"
655run_test "bdev_write_zeroes" $testdir/bdevperf/bdevperf --json "$conf_file" -q 128 -o 4096 -w write_zeroes -t 1 "$env_ctx"
656
657# test json config not enclosed with {}
658run_test "bdev_json_nonenclosed" $testdir/bdevperf/bdevperf --json "$nonenclosed_conf_file" -q 128 -o 4096 -w write_zeroes -t 1 "$env_ctx" || true
659
660# test json config "subsystems" not with array
661run_test "bdev_json_nonarray" $testdir/bdevperf/bdevperf --json "$nonarray_conf_file" -q 128 -o 4096 -w write_zeroes -t 1 "$env_ctx" || true
662
663if [[ $test_type == bdev ]]; then
664	run_test "bdev_qos" qos_test_suite "$env_ctx"
665	run_test "bdev_qd_sampling" qd_sampling_test_suite "$env_ctx"
666	run_test "bdev_error" error_test_suite "$env_ctx"
667	run_test "bdev_stat" stat_test_suite "$env_ctx"
668fi
669
670# Temporarily disabled - infinite loop
671# if [ $RUN_NIGHTLY -eq 1 ]; then
672# run_test "bdev_reset" $testdir/bdevperf/bdevperf --json "$conf_file" -q 16 -w reset -o 4096 -t 60 "$env_ctx"
673# fi
674
675# Bdev and configuration cleanup below this line
676#-----------------------------------------------------
677
678trap - SIGINT SIGTERM EXIT
679cleanup
680