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