Merge branch 'fix-randtrimwrite' of https://github.com/minwooim/fio
[fio.git] / t / zbd / test-zbd-support
CommitLineData
191d1d1a
BVA
1#!/bin/bash
2#
3# Copyright (C) 2018 Western Digital Corporation or its affiliates.
4#
5# This file is released under the GPL.
6
7usage() {
17293ae3
SK
8 echo "Usage: $(basename "$0") [OPTIONS] <test target device file>"
9 echo "Options:"
10 echo -e "\t-d Run fio with valgrind using DRD tool"
11 echo -e "\t-e Run fio with valgrind using helgrind tool"
12 echo -e "\t-v Run fio with valgrind --read-var-info option"
13 echo -e "\t-l Test with libzbc ioengine"
14 echo -e "\t-r Reset all zones before test start"
ccf9d1ef 15 echo -e "\t-w Reset all zones before executing each write test case"
7ce7422a 16 echo -e "\t-o <max_open_zones> Run fio with max_open_zones limit"
17293ae3 17 echo -e "\t-t <test #> Run only a single test case with specified number"
12067650 18 echo -e "\t-s <test #> Start testing from the case with the specified number"
56e87b2f 19 echo -e "\t-q Quit the test run after any failed test"
17293ae3 20 echo -e "\t-z Run fio with debug=zbd option"
0360d61f 21 echo -e "\t-u Use io_uring ioengine in place of libaio"
191d1d1a
BVA
22}
23
24max() {
25 if [ "$1" -gt "$2" ]; then
26 echo "$1"
27 else
28 echo "$2"
29 fi
30}
31
32min() {
33 if [ "$1" -lt "$2" ]; then
34 echo "$1"
35 else
36 echo "$2"
37 fi
38}
39
6dcb098d
DF
40ioengine() {
41 if [ -n "$use_libzbc" ]; then
42 echo -n "--ioengine=libzbc"
0360d61f
DF
43 elif [ "$1" = "libaio" -a -n "$force_io_uring" ]; then
44 echo -n "--ioengine=io_uring"
6dcb098d
DF
45 else
46 echo -n "--ioengine=$1"
47 fi
48}
49
996ac91f
SK
50get_dev_path_by_id() {
51 for d in /sys/block/* /sys/block/*/*; do
52 if [[ ! -r "${d}/dev" ]]; then
53 continue
54 fi
55 if [[ "${1}" == "$(<"${d}/dev")" ]]; then
56 echo "/dev/${d##*/}"
57 return 0
58 fi
59 done
60 return 1
61}
62
b6002e78
SK
63get_scsi_device_path() {
64 local dev="${1}"
65 local syspath
66
67 syspath=/sys/block/"${dev##*/}"/device
68 if [[ -r /sys/class/scsi_generic/"${dev##*/}"/device ]]; then
69 syspath=/sys/class/scsi_generic/"${dev##*/}"/device
70 fi
71 realpath "$syspath"
72}
73
996ac91f
SK
74dm_destination_dev_set_io_scheduler() {
75 local dev=$1 sched=$2
76 local dest_dev_id dest_dev path
77
78 has_command dmsetup || return 1
79
80 while read -r dest_dev_id; do
81 if ! dest_dev=$(get_dev_path_by_id "${dest_dev_id}"); then
82 continue
83 fi
84 path=${dest_dev/dev/sys\/block}/queue/scheduler
85 if [[ ! -w ${path} ]]; then
86 echo "Can not set scheduler of device mapper destination: ${dest_dev}"
87 continue
88 fi
89 echo "${2}" > "${path}"
90 done < <(dmsetup table "$(<"/sys/block/$dev/dm/name")" |
91 sed -n 's/.* \([0-9]*:[0-9]*\).*/\1/p')
92}
93
94dev_has_dm_map() {
95 local dev=${1} target_type=${2}
96 local dm_name
97
98 has_command dmsetup || return 1
99
100 dm_name=$(<"/sys/block/$dev/dm/name")
101 if ! dmsetup status "${dm_name}" | grep -qe "${target_type}"; then
102 return 1
103 fi
104 if dmsetup status "${dm_name}" | grep -v "${target_type}"; then
105 return 1
106 fi
107 return 0
108}
109
191d1d1a
BVA
110set_io_scheduler() {
111 local dev=$1 sched=$2
112
113 [ -e "/sys/block/$dev" ] || return $?
114 if [ -e "/sys/block/$dev/mq" ]; then
115 case "$sched" in
116 noop) sched=none;;
117 deadline) sched=mq-deadline;;
118 esac
119 else
120 case "$sched" in
121 none) sched=noop;;
122 mq-deadline) sched=deadline;;
123 esac
124 fi
125
996ac91f
SK
126 if [ -w "/sys/block/$dev/queue/scheduler" ]; then
127 echo "$sched" >"/sys/block/$dev/queue/scheduler"
128 elif [ -r "/sys/block/$dev/dm/name" ] &&
129 ( dev_has_dm_map "$dev" linear ||
130 dev_has_dm_map "$dev" flakey ||
131 dev_has_dm_map "$dev" crypt ); then
132 dm_destination_dev_set_io_scheduler "$dev" "$sched"
133 else
134 echo "can not set io scheduler"
135 exit 1
136 fi
191d1d1a
BVA
137}
138
139check_read() {
140 local read
141
142 read=$(fio_read <"${logfile}.${test_number}")
143 echo "read: $read <> $1" >> "${logfile}.${test_number}"
144 [ "$read" = "$1" ]
145}
146
147check_written() {
148 local written
149
150 written=$(fio_written <"${logfile}.${test_number}")
151 echo "written: $written <> $1" >> "${logfile}.${test_number}"
152 [ "$written" = "$1" ]
153}
154
155# Compare the reset count from the log file with reset count $2 using operator
156# $1 (=, -ge, -gt, -le, -lt).
157check_reset_count() {
158 local reset_count
159
160 reset_count=$(fio_reset_count <"${logfile}.${test_number}")
161 echo "reset_count: test $reset_count $1 $2" >> "${logfile}.${test_number}"
162 eval "[ '$reset_count' '$1' '$2' ]"
163}
164
0d578085
DF
165# Check log for failed assertions and crashes. Without these checks,
166# a test can succeed even when these events happen, but it must fail.
167check_log() {
168 [ ! -f "${logfile}.${1}" ] && return 0
169 ! grep -q -e "Assertion " -e "Aborted " "${logfile}.${1}"
170}
171
191d1d1a
BVA
172# Whether or not $1 (/dev/...) is a SCSI device.
173is_scsi_device() {
174 local d f
175
176 d=$(basename "$dev")
177 for f in /sys/class/scsi_device/*/device/block/"$d"; do
178 [ -e "$f" ] && return 0
179 done
180 return 1
181}
182
7ce7422a
SK
183job_var_opts_exclude() {
184 local o
185 local ex_key="${1}"
186
187 for o in "${job_var_opts[@]}"; do
188 if [[ ${o} =~ "${ex_key}" ]]; then
189 continue
190 fi
191 echo -n "${o}"
192 done
193}
194
195has_max_open_zones() {
196 while (($# > 1)); do
197 if [[ ${1} =~ "--max_open_zones" ]]; then
198 return 0
199 fi
200 shift
201 done
202 return 1
203}
204
191d1d1a 205run_fio() {
97e41ee4 206 local fio opts
191d1d1a
BVA
207
208 fio=$(dirname "$0")/../../fio
209
7ce7422a
SK
210 opts=(${global_var_opts[@]})
211 opts+=("--max-jobs=16" "--aux-path=/tmp" "--allow_file_create=0" \
212 "--significant_figures=10" "$@")
213 # When max_open_zones option is specified to this test script, add
214 # max_open_zones option to fio command unless the test case already add it.
215 if [[ -n ${max_open_zones_opt} ]] && ! has_max_open_zones "${opts[@]}"; then
216 opts+=("--max_open_zones=${max_open_zones_opt}")
217 fi
97e41ee4 218 { echo; echo "fio ${opts[*]}"; echo; } >>"${logfile}.${test_number}"
191d1d1a 219
97e41ee4 220 "${dynamic_analyzer[@]}" "$fio" "${opts[@]}"
191d1d1a
BVA
221}
222
223run_one_fio_job() {
224 local r
225
226 r=$(((RANDOM << 16) | RANDOM))
227 run_fio --name="$dev" --filename="$dev" "$@" --randseed="$r" \
228 --thread=1 --direct=1
229}
230
8f601b44
SK
231write_and_run_one_fio_job() {
232 local r
233 local write_offset="${1}"
234 local write_size="${2}"
7ce7422a 235 local -a write_opts
8f601b44
SK
236
237 shift 2
238 r=$(((RANDOM << 16) | RANDOM))
7ce7422a 239 write_opts=(--name="write_job" --rw=write "$(ioengine "psync")" \
79201772 240 --bs="${min_seq_write_size}" --zonemode=zbd \
7ce7422a
SK
241 --zonesize="${zone_size}" --thread=1 --direct=1 \
242 --offset="${write_offset}" --size="${write_size}")
243 write_opts+=("${job_var_opts[@]}")
244 run_fio --filename="$dev" --randseed="$r" "${write_opts[@]}" \
8f601b44
SK
245 --name="$dev" --wait_for="write_job" "$@" --thread=1 --direct=1
246}
247
191d1d1a
BVA
248# Run fio on the first four sequential zones of the disk.
249run_fio_on_seq() {
250 local opts=()
251
252 opts+=("--offset=$((first_sequential_zone_sector * 512))")
253 opts+=("--size=$((4 * zone_size))" "--zonemode=zbd")
254 if [ -z "$is_zbd" ]; then
255 opts+=("--zonesize=${zone_size}")
256 fi
257 run_one_fio_job "${opts[@]}" "$@"
258}
259
ccf9d1ef
SK
260# Prepare for write test by resetting zones. When reset_before_write or
261# max_open_zones option is specified, reset all zones of the test target to
262# ensure that zones out of the test target range do not have open zones. This
263# allows the write test to the target range to be able to open zones up to
264# max_open_zones limit specified as the option or obtained from sysfs.
b34eb155 265prep_write() {
ccf9d1ef
SK
266 [[ -n "${reset_before_write}" || -n "${max_open_zones_opt}" ]] &&
267 [[ -n "${is_zbd}" ]] && reset_zone "${dev}" -1
b34eb155
SK
268}
269
d480b019
SK
270SKIP_TESTCASE=255
271
272require_scsi_dev() {
273 if ! is_scsi_device "$dev"; then
274 SKIP_REASON="$dev is not a SCSI device"
275 return 1
276 fi
277 return 0
278}
279
280require_conv_zone_bytes() {
281 local req_bytes=${1}
282
283 if ((req_bytes > first_sequential_zone_sector * 512)); then
284 SKIP_REASON="$dev does not have enough conventional zones"
285 return 1
286 fi
287 return 0
288}
289
290require_zbd() {
291 if [[ -z ${is_zbd} ]]; then
292 SKIP_REASON="$dev is not a zoned block device"
293 return 1
294 fi
295 return 0
296}
297
298require_regular_block_dev() {
299 if [[ -n ${is_zbd} ]]; then
300 SKIP_REASON="$dev is not a regular block device"
301 return 1
302 fi
303 return 0
304}
305
59c3200d
AK
306require_block_dev() {
307 if [[ -b "$realdev" ]]; then
308 return 0
309 fi
310 SKIP_REASON="$dev is not a block device"
311 return 1
312}
313
1200ac6a
SK
314require_seq_zones() {
315 local req_seq_zones=${1}
316 local seq_bytes=$((disk_size - first_sequential_zone_sector * 512))
317
318 if ((req_seq_zones > seq_bytes / zone_size)); then
319 SKIP_REASON="$dev does not have $req_seq_zones sequential zones"
320 return 1
321 fi
322 return 0
323}
324
a66a8fab
SK
325require_conv_zones() {
326 local req_c_zones=${1}
327 local conv_bytes=$((first_sequential_zone_sector * 512))
328
329 if ((req_c_zones > conv_bytes / zone_size)); then
330 SKIP_REASON="$dev does not have $req_c_zones conventional zones"
331 return 1
332 fi
333 return 0
334}
335
26faead0
SK
336require_max_open_zones() {
337 local min=${1}
338
339 if ((max_open_zones !=0 && max_open_zones < min)); then
340 SKIP_REASON="max_open_zones of $dev is smaller than $min"
341 return 1
342 fi
343 return 0
344}
345
1a5411cd
SK
346require_max_active_zones() {
347 local min=${1}
348
349 if ((max_active_zones == 0)); then
350 SKIP_REASON="$dev does not have max_active_zones limit"
351 return 1
352 fi
353 if ((max_active_zones < min)); then
354 SKIP_REASON="max_active_zones of $dev is smaller than $min"
355 return 1
356 fi
357 return 0
358}
359
96afc233
SK
360require_no_max_active_zones() {
361 if ((max_active_zones > 0)); then
362 SKIP_REASON="$dev has max_active_zones limit"
363 return 1
364 fi
365 return 0
366}
367
b6002e78
SK
368require_badblock() {
369 local syspath sdebug_path
370
371 syspath=/sys/kernel/config/nullb/"${dev##*/}"
372 if [[ -d "${syspath}" ]]; then
373 if [[ ! -w "${syspath}/badblocks" ]]; then
374 SKIP_REASON="$dev does not have badblocks attribute"
375 return 1
376 fi
377 if [[ ! -w "${syspath}/badblocks_once" ]]; then
378 SKIP_REASON="$dev does not have badblocks_once attribute"
379 return 1
380 fi
381 if ((! $(<"${syspath}/badblocks_once"))); then
382 SKIP_REASON="badblocks_once attribute is not set for $dev"
383 return 1
384 fi
385 return 0
386 fi
387
388 syspath=$(get_scsi_device_path "$dev")
389 if [[ -r ${syspath}/model &&
390 $(<"${syspath}"/model) =~ scsi_debug ]]; then
391 sdebug_path=/sys/kernel/debug/scsi_debug/${syspath##*/}
392 if [[ ! -w "$sdebug_path"/error ]]; then
393 SKIP_REASON="$dev does not have write error injection"
394 return 1
395 fi
396 return 0
397 fi
398
399 SKIP_REASON="$dev does not support either badblocks or error injection"
400 return 1
401}
402
403require_nullb() {
404 if [[ ! -d /sys/kernel/config/nullb/"${dev##*/}" ]]; then
405 SKIP_REASON="$dev is not null_blk"
406 return 1
407 fi
408 return 0
409}
410
59c3200d 411# Check whether buffered writes are refused for block devices.
191d1d1a 412test1() {
59c3200d 413 require_block_dev || return $SKIP_TESTCASE
191d1d1a 414 run_fio --name=job1 --filename="$dev" --rw=write --direct=0 --bs=4K \
6dcb098d 415 "$(ioengine "psync")" --size="${zone_size}" --thread=1 \
191d1d1a
BVA
416 --zonemode=zbd --zonesize="${zone_size}" 2>&1 |
417 tee -a "${logfile}.${test_number}" |
418 grep -q 'Using direct I/O is mandatory for writing to ZBD drives'
419 local fio_rc=${PIPESTATUS[0]} grep_rc=${PIPESTATUS[2]}
420 case "$fio_rc" in
421 0|1) ;;
422 *) return "$fio_rc"
423 esac
424 if [ -n "$is_zbd" ]; then
425 [ "$grep_rc" = 0 ]
426 else
427 [ "$grep_rc" != 0 ]
428 fi
429}
430
431# Block size exceeds zone size.
432test2() {
433 local bs off opts=() rc
434
435 off=$(((first_sequential_zone_sector + 2 * sectors_per_zone) * 512))
436 bs=$((2 * zone_size))
6dcb098d 437 opts+=("$(ioengine "psync")")
191d1d1a
BVA
438 opts+=("--name=job1" "--filename=$dev" "--rw=write" "--direct=1")
439 opts+=("--zonemode=zbd" "--offset=$off" "--bs=$bs" "--size=$bs")
440 if [ -z "$is_zbd" ]; then
441 opts+=("--zonesize=${zone_size}")
442 fi
0ed2fbfb
DF
443 run_fio "${opts[@]}" >> "${logfile}.${test_number}" 2>&1 && return 1
444 grep -q 'buflen exceeds zone size' "${logfile}.${test_number}"
191d1d1a
BVA
445}
446
447# Run fio against an empty zone. This causes fio to report "No I/O performed".
448test3() {
449 local off opts=() rc
450
1200ac6a 451 require_seq_zones 129 || return $SKIP_TESTCASE
191d1d1a
BVA
452 off=$((first_sequential_zone_sector * 512 + 128 * zone_size))
453 size=$((zone_size))
454 [ -n "$is_zbd" ] && reset_zone "$dev" $((off / 512))
455 opts+=("--name=$dev" "--filename=$dev" "--offset=$off" "--bs=4K")
456 opts+=("--size=$size" "--zonemode=zbd")
6dcb098d 457 opts+=("$(ioengine "psync")" "--rw=read" "--direct=1" "--thread=1")
191d1d1a
BVA
458 if [ -z "$is_zbd" ]; then
459 opts+=("--zonesize=${zone_size}")
460 fi
461 run_fio "${opts[@]}" >> "${logfile}.${test_number}" 2>&1 || return $?
bbd6f1bb 462 ! grep -q 'READ:' "${logfile}.${test_number}"
191d1d1a
BVA
463}
464
465# Run fio with --read_beyond_wp=1 against an empty zone.
466test4() {
467 local off opts=()
468
1200ac6a 469 require_seq_zones 130 || return $SKIP_TESTCASE
191d1d1a
BVA
470 off=$((first_sequential_zone_sector * 512 + 129 * zone_size))
471 size=$((zone_size))
472 [ -n "$is_zbd" ] && reset_zone "$dev" $((off / 512))
1f5dd7fa 473 opts+=("--name=$dev" "--filename=$dev" "--offset=$off")
79201772 474 opts+=(--bs="$(min $((min_seq_write_size * 256)) $size)")
191d1d1a 475 opts+=("--size=$size" "--thread=1" "--read_beyond_wp=1")
6dcb098d 476 opts+=("$(ioengine "psync")" "--rw=read" "--direct=1" "--disable_lat=1")
191d1d1a 477 opts+=("--zonemode=zbd" "--zonesize=${zone_size}")
7d5a66e1
DF
478 run_fio "${opts[@]}" >> "${logfile}.${test_number}" 2>&1
479 fio_rc=$?
480 if [[ $unrestricted_reads != 0 ]]; then
481 if [[ $fio_rc != 0 ]]; then
482 return "$fio_rc"
483 fi
484 check_read $size || return $?
485 else
486 [ $fio_rc == 0 ] && return 1 || return 0
487 fi
191d1d1a
BVA
488}
489
490# Sequential write to sequential zones.
491test5() {
1ae82d67 492 local size off capacity bs
191d1d1a 493
b34eb155 494 prep_write
d7c7539f
HH
495 off=$((first_sequential_zone_sector * 512))
496 capacity=$(total_zone_capacity 4 $off $dev)
191d1d1a 497 size=$((4 * zone_size))
79201772 498 bs=$(min "$(max $((zone_size / 64)) "$min_seq_write_size")" "$zone_cap_bs")
6dcb098d 499 run_fio_on_seq "$(ioengine "psync")" --iodepth=1 --rw=write \
1ae82d67 500 --bs="$bs" --do_verify=1 --verify=md5 \
191d1d1a 501 >>"${logfile}.${test_number}" 2>&1 || return $?
d7c7539f
HH
502 check_written $capacity || return $?
503 check_read $capacity || return $?
191d1d1a
BVA
504}
505
0123751c 506# Sequential read from sequential zones.
191d1d1a 507test6() {
1ae82d67 508 local size off capacity bs
191d1d1a 509
b34eb155 510 prep_write
d7c7539f
HH
511 off=$((first_sequential_zone_sector * 512))
512 capacity=$(total_zone_capacity 4 $off $dev)
191d1d1a 513 size=$((4 * zone_size))
79201772 514 bs=$(min "$(max $((zone_size / 64)) "$min_seq_write_size")" "$zone_cap_bs")
0123751c
SK
515 write_and_run_one_fio_job \
516 $((first_sequential_zone_sector * 512)) "${size}" \
d7c7539f 517 --offset="${off}" \
0123751c 518 --size="${size}" --zonemode=zbd --zonesize="${zone_size}" \
1ae82d67 519 "$(ioengine "psync")" --iodepth=1 --rw=read --bs="$bs" \
0123751c 520 >>"${logfile}.${test_number}" 2>&1 || return $?
d7c7539f 521 check_read $capacity || return $?
191d1d1a
BVA
522}
523
524# Random write to sequential zones, libaio, queue depth 1.
525test7() {
526 local size=$((zone_size))
d7c7539f 527 local off capacity
191d1d1a 528
b34eb155 529 prep_write
d7c7539f
HH
530 off=$((first_sequential_zone_sector * 512))
531 capacity=$(total_zone_capacity 1 $off $dev)
6dcb098d 532 run_fio_on_seq "$(ioengine "libaio")" --iodepth=1 --rw=randwrite \
191d1d1a
BVA
533 --bs="$(min 16384 "${zone_size}")" \
534 --do_verify=1 --verify=md5 --size="$size" \
535 >>"${logfile}.${test_number}" 2>&1 || return $?
d7c7539f
HH
536 check_written $capacity || return $?
537 check_read $capacity || return $?
191d1d1a
BVA
538}
539
540# Random write to sequential zones, libaio, queue depth 64.
541test8() {
d7c7539f 542 local size off capacity
191d1d1a 543
b34eb155 544 prep_write
191d1d1a 545 size=$((4 * zone_size))
d7c7539f
HH
546 off=$((first_sequential_zone_sector * 512))
547 capacity=$(total_zone_capacity 4 $off $dev)
6dcb098d 548 run_fio_on_seq "$(ioengine "libaio")" --iodepth=64 --rw=randwrite \
191d1d1a
BVA
549 --bs="$(min 16384 "${zone_size}")" \
550 --do_verify=1 --verify=md5 \
551 >>"${logfile}.${test_number}" 2>&1 || return $?
d7c7539f
HH
552 check_written $capacity || return $?
553 check_read $capacity || return $?
191d1d1a
BVA
554}
555
556# Random write to sequential zones, sg, queue depth 1.
557test9() {
558 local size
559
d480b019 560 require_scsi_dev || return $SKIP_TESTCASE
191d1d1a 561
b34eb155 562 prep_write
191d1d1a 563 size=$((4 * zone_size))
6dcb098d
DF
564 run_fio_on_seq --ioengine=sg \
565 --iodepth=1 --rw=randwrite --bs=16K \
191d1d1a
BVA
566 --do_verify=1 --verify=md5 \
567 >>"${logfile}.${test_number}" 2>&1 || return $?
568 check_written $size || return $?
569 check_read $size || return $?
570}
571
572# Random write to sequential zones, sg, queue depth 64.
573test10() {
574 local size
575
d480b019 576 require_scsi_dev || return $SKIP_TESTCASE
191d1d1a 577
b34eb155 578 prep_write
191d1d1a 579 size=$((4 * zone_size))
6dcb098d
DF
580 run_fio_on_seq --ioengine=sg \
581 --iodepth=64 --rw=randwrite --bs=16K \
191d1d1a
BVA
582 --do_verify=1 --verify=md5 \
583 >>"${logfile}.${test_number}" 2>&1 || return $?
584 check_written $size || return $?
585 check_read $size || return $?
586}
587
588# Random write to sequential zones, libaio, queue depth 64, random block size.
589test11() {
d7c7539f 590 local size off capacity
191d1d1a 591
b34eb155 592 prep_write
191d1d1a 593 size=$((4 * zone_size))
d7c7539f
HH
594 off=$((first_sequential_zone_sector * 512))
595 capacity=$(total_zone_capacity 4 $off $dev)
6dcb098d 596 run_fio_on_seq "$(ioengine "libaio")" --iodepth=64 --rw=randwrite \
191d1d1a
BVA
597 --bsrange=4K-64K --do_verify=1 --verify=md5 \
598 --debug=zbd >>"${logfile}.${test_number}" 2>&1 || return $?
d7c7539f
HH
599 check_written $capacity || return $?
600 check_read $capacity || return $?
191d1d1a
BVA
601}
602
603# Random write to sequential zones, libaio, queue depth 64, max 1 open zone.
604test12() {
d7c7539f 605 local size off capacity
191d1d1a 606
5b4c9c4e
SK
607 [ -n "$is_zbd" ] && reset_zone "$dev" -1
608
191d1d1a 609 size=$((8 * zone_size))
d7c7539f
HH
610 off=$((first_sequential_zone_sector * 512))
611 capacity=$(total_zone_capacity 8 $off $dev)
6dcb098d 612 run_fio_on_seq "$(ioengine "libaio")" --iodepth=64 --rw=randwrite --bs=16K \
191d1d1a
BVA
613 --max_open_zones=1 --size=$size --do_verify=1 --verify=md5 \
614 --debug=zbd >>"${logfile}.${test_number}" 2>&1 || return $?
d7c7539f
HH
615 check_written $capacity || return $?
616 check_read $capacity || return $?
191d1d1a
BVA
617}
618
619# Random write to sequential zones, libaio, queue depth 64, max 4 open zones.
620test13() {
d7c7539f 621 local size off capacity
191d1d1a 622
26faead0
SK
623 require_max_open_zones 4 || return $SKIP_TESTCASE
624
5b4c9c4e
SK
625 [ -n "$is_zbd" ] && reset_zone "$dev" -1
626
191d1d1a 627 size=$((8 * zone_size))
d7c7539f
HH
628 off=$((first_sequential_zone_sector * 512))
629 capacity=$(total_zone_capacity 8 $off $dev)
6dcb098d 630 run_fio_on_seq "$(ioengine "libaio")" --iodepth=64 --rw=randwrite --bs=16K \
191d1d1a
BVA
631 --max_open_zones=4 --size=$size --do_verify=1 --verify=md5 \
632 --debug=zbd \
633 >>"${logfile}.${test_number}" 2>&1 || return $?
d7c7539f
HH
634 check_written $capacity || return $?
635 check_read $capacity || return $?
191d1d1a
BVA
636}
637
638# Random write to conventional zones.
639test14() {
c6950209 640 local off size
191d1d1a 641
c6950209
DF
642 if ! result=($(first_online_zone "$dev")); then
643 echo "Failed to determine first online zone"
644 exit 1
645 fi
646 off=${result[0]}
b34eb155 647 prep_write
191d1d1a 648 size=$((16 * 2**20)) # 20 MB
d480b019
SK
649 require_conv_zone_bytes "${size}" || return $SKIP_TESTCASE
650
6dcb098d 651 run_one_fio_job "$(ioengine "libaio")" --iodepth=64 --rw=randwrite --bs=16K \
191d1d1a 652 --zonemode=zbd --zonesize="${zone_size}" --do_verify=1 \
c6950209 653 --verify=md5 --offset=$off --size=$size\
191d1d1a
BVA
654 >>"${logfile}.${test_number}" 2>&1 || return $?
655 check_written $((size)) || return $?
656 check_read $((size)) || return $?
657}
658
659# Sequential read on a mix of empty and full zones.
660test15() {
1ae82d67 661 local i off size bs
d7c7539f 662 local w_off w_size w_capacity
191d1d1a
BVA
663
664 for ((i=0;i<4;i++)); do
665 [ -n "$is_zbd" ] &&
666 reset_zone "$dev" $((first_sequential_zone_sector +
667 i*sectors_per_zone))
668 done
b34eb155 669 prep_write
291aa0a7
SK
670 w_off=$(((first_sequential_zone_sector + 2 * sectors_per_zone) * 512))
671 w_size=$((2 * zone_size))
d7c7539f 672 w_capacity=$(total_zone_capacity 2 $w_off $dev)
191d1d1a
BVA
673 off=$((first_sequential_zone_sector * 512))
674 size=$((4 * zone_size))
1ae82d67 675 bs=$(min $((zone_size / 16)) "$zone_cap_bs")
291aa0a7 676 write_and_run_one_fio_job "${w_off}" "${w_size}" \
1ae82d67 677 "$(ioengine "psync")" --rw=read --bs="$bs" \
191d1d1a
BVA
678 --zonemode=zbd --zonesize="${zone_size}" --offset=$off \
679 --size=$((size)) >>"${logfile}.${test_number}" 2>&1 ||
680 return $?
d7c7539f
HH
681 check_written $((w_capacity)) || return $?
682 check_read $((w_capacity))
191d1d1a
BVA
683}
684
7285b445 685# Random read on a mix of empty and full zones.
191d1d1a
BVA
686test16() {
687 local off size
d7c7539f 688 local i w_off w_size w_capacity
191d1d1a 689
7285b445
SK
690 for ((i=0;i<4;i++)); do
691 [ -n "$is_zbd" ] &&
692 reset_zone "$dev" $((first_sequential_zone_sector +
693 i*sectors_per_zone))
694 done
b34eb155 695 prep_write
7285b445
SK
696 w_off=$(((first_sequential_zone_sector + 2 * sectors_per_zone) * 512))
697 w_size=$((2 * zone_size))
d7c7539f 698 w_capacity=$(total_zone_capacity 2 $w_off $dev)
191d1d1a
BVA
699 off=$((first_sequential_zone_sector * 512))
700 size=$((4 * zone_size))
7285b445
SK
701 write_and_run_one_fio_job "${w_off}" "${w_size}" \
702 "$(ioengine "libaio")" --iodepth=64 --rw=randread --bs=16K \
191d1d1a
BVA
703 --zonemode=zbd --zonesize="${zone_size}" --offset=$off \
704 --size=$size >>"${logfile}.${test_number}" 2>&1 || return $?
d7c7539f 705 check_written $w_capacity || return $?
191d1d1a
BVA
706 check_read $size || return $?
707}
708
709# Random reads and writes in the last zone.
710test17() {
c6950209 711 local io off last read size written
191d1d1a
BVA
712
713 off=$(((disk_size / zone_size - 1) * zone_size))
714 size=$((disk_size - off))
c6950209
DF
715 if ! last=($(last_online_zone "$dev")); then
716 echo "Failed to determine last online zone"
717 exit 1
718 fi
719 if [[ "$((last * 512))" -lt "$off" ]]; then
720 off=$((last * 512))
721 size=$zone_size
722 fi
191d1d1a
BVA
723 if [ -n "$is_zbd" ]; then
724 reset_zone "$dev" $((off / 512)) || return $?
725 fi
b34eb155 726 prep_write
6dcb098d 727 run_one_fio_job "$(ioengine "libaio")" --iodepth=8 --rw=randrw --bs=4K \
191d1d1a 728 --zonemode=zbd --zonesize="${zone_size}" \
c6950209
DF
729 --offset=$off --loops=2 --norandommap=1 \
730 --size="$size"\
191d1d1a
BVA
731 >>"${logfile}.${test_number}" 2>&1 || return $?
732 written=$(fio_written <"${logfile}.${test_number}")
733 read=$(fio_read <"${logfile}.${test_number}")
734 io=$((written + read))
735 echo "Total number of bytes read and written: $io <> $size" \
736 >>"${logfile}.${test_number}"
737 [ $io = $((size * 2)) ];
738}
739
740# Out-of-range zone reset threshold and frequency parameters.
741test18() {
742 run_fio_on_seq --zone_reset_threshold=-1 |&
743 tee -a "${logfile}.${test_number}" |
744 grep -q 'value out of range' || return $?
745}
746
747test19() {
748 run_fio_on_seq --zone_reset_threshold=2 |&
749 tee -a "${logfile}.${test_number}" |
750 grep -q 'value out of range' || return $?
751}
752
753test20() {
754 run_fio_on_seq --zone_reset_threshold=.4:.6 |&
755 tee -a "${logfile}.${test_number}" |
756 grep -q 'the list exceeding max length' || return $?
757}
758
759test21() {
760 run_fio_on_seq --zone_reset_frequency=-1 |&
761 tee -a "${logfile}.${test_number}" |
762 grep -q 'value out of range' || return $?
763}
764
765test22() {
766 run_fio_on_seq --zone_reset_frequency=2 |&
767 tee -a "${logfile}.${test_number}" |
768 grep -q 'value out of range' || return $?
769}
770
771test23() {
772 run_fio_on_seq --zone_reset_frequency=.4:.6 |&
773 tee -a "${logfile}.${test_number}" |
774 grep -q 'the list exceeding max length' || return $?
775}
776
777test24() {
778 local bs loops=9 size=$((zone_size))
d7c7539f
HH
779 local off capacity
780
b34eb155 781 prep_write
d7c7539f
HH
782 off=$((first_sequential_zone_sector * 512))
783 capacity=$(total_zone_capacity 1 $off $dev)
191d1d1a
BVA
784
785 bs=$(min $((256*1024)) "$zone_size")
6dcb098d
DF
786 run_fio_on_seq "$(ioengine "psync")" --rw=write --bs="$bs" \
787 --size=$size --loops=$loops \
191d1d1a
BVA
788 --zone_reset_frequency=.01 --zone_reset_threshold=.90 \
789 >> "${logfile}.${test_number}" 2>&1 || return $?
d7c7539f 790 check_written $((capacity * loops)) || return $?
191d1d1a
BVA
791 check_reset_count -eq 8 ||
792 check_reset_count -eq 9 ||
793 check_reset_count -eq 10 || return $?
794}
795
796# Multiple non-overlapping sequential write jobs for the same drive.
797test25() {
798 local i opts=()
799
800 for ((i=0;i<16;i++)); do
801 [ -n "$is_zbd" ] &&
802 reset_zone "$dev" $((first_sequential_zone_sector + i*sectors_per_zone))
803 done
b34eb155 804 prep_write
191d1d1a
BVA
805 for ((i=0;i<16;i++)); do
806 opts+=("--name=job$i" "--filename=$dev" "--thread=1" "--direct=1")
807 opts+=("--offset=$((first_sequential_zone_sector*512 + zone_size*i))")
6dcb098d 808 opts+=("--size=$zone_size" "$(ioengine "psync")" "--rw=write" "--bs=16K")
191d1d1a 809 opts+=("--zonemode=zbd" "--zonesize=${zone_size}" "--group_reporting=1")
7ce7422a 810 opts+=(${job_var_opts[@]})
191d1d1a
BVA
811 done
812 run_fio "${opts[@]}" >> "${logfile}.${test_number}" 2>&1 || return $?
813}
814
815write_to_first_seq_zone() {
816 local loops=4 r
d7c7539f
HH
817 local off capacity
818
b34eb155 819 prep_write
d7c7539f
HH
820 off=$((first_sequential_zone_sector * 512))
821 capacity=$(total_zone_capacity 1 $off $dev)
191d1d1a
BVA
822
823 r=$(((RANDOM << 16) | RANDOM))
6dcb098d 824 run_fio --name="$dev" --filename="$dev" "$(ioengine "psync")" --rw="$1" \
191d1d1a 825 --thread=1 --do_verify=1 --verify=md5 --direct=1 --bs=4K \
d7c7539f
HH
826 --offset=$off \
827 --size=$zone_size --loops=$loops --randseed="$r" \
191d1d1a
BVA
828 --zonemode=zbd --zonesize="${zone_size}" --group_reporting=1 \
829 --gtod_reduce=1 >> "${logfile}.${test_number}" 2>&1 || return $?
d7c7539f 830 check_written $((loops * capacity)) || return $?
191d1d1a
BVA
831}
832
833# Overwrite the first sequential zone four times sequentially.
834test26() {
835 write_to_first_seq_zone write
836}
837
838# Overwrite the first sequential zone four times using random writes.
839test27() {
840 write_to_first_seq_zone randwrite
841}
842
843# Multiple overlapping random write jobs for the same drive.
844test28() {
845 local i jobs=16 off opts
846
1200ac6a 847 require_seq_zones 65 || return $SKIP_TESTCASE
191d1d1a
BVA
848 off=$((first_sequential_zone_sector * 512 + 64 * zone_size))
849 [ -n "$is_zbd" ] && reset_zone "$dev" $((off / 512))
b34eb155 850 prep_write
191d1d1a 851 opts=("--debug=zbd")
d7c7539f 852 capacity=$(total_zone_capacity 1 $off $dev)
191d1d1a
BVA
853 for ((i=0;i<jobs;i++)); do
854 opts+=("--name=job$i" "--filename=$dev" "--offset=$off" "--bs=16K")
d7c7539f 855 opts+=("--size=$zone_size" "--io_size=$capacity" "$(ioengine "psync")" "--rw=randwrite")
191d1d1a
BVA
856 opts+=("--thread=1" "--direct=1" "--zonemode=zbd")
857 opts+=("--zonesize=${zone_size}" "--group_reporting=1")
7ce7422a 858 opts+=(${job_var_opts[@]})
191d1d1a
BVA
859 done
860 run_fio "${opts[@]}" >> "${logfile}.${test_number}" 2>&1 || return $?
d7c7539f 861 check_written $((jobs * $capacity)) || return $?
191d1d1a
BVA
862 check_reset_count -eq $jobs ||
863 check_reset_count -eq $((jobs - 1)) ||
864 return $?
865}
866
867# Multiple overlapping random write jobs for the same drive and with a limited
868# number of open zones.
869test29() {
870 local i jobs=16 off opts=()
871
1200ac6a 872 require_seq_zones 80 || return $SKIP_TESTCASE
191d1d1a
BVA
873 off=$((first_sequential_zone_sector * 512 + 64 * zone_size))
874 size=$((16*zone_size))
5b4c9c4e
SK
875
876 [ -n "$is_zbd" ] && reset_zone "$dev" -1
877
191d1d1a
BVA
878 opts=("--debug=zbd")
879 for ((i=0;i<jobs;i++)); do
880 opts+=("--name=job$i" "--filename=$dev" "--offset=$off" "--bs=16K")
881 opts+=("--size=$size" "--io_size=$zone_size" "--thread=1")
6dcb098d 882 opts+=("$(ioengine "psync")" "--rw=randwrite" "--direct=1")
191d1d1a
BVA
883 opts+=("--max_open_zones=4" "--group_reporting=1")
884 opts+=("--zonemode=zbd" "--zonesize=${zone_size}")
7ce7422a
SK
885 # max_open_zones is already specified
886 opts+=($(job_var_opts_exclude "--max_open_zones"))
191d1d1a
BVA
887 done
888 run_fio "${opts[@]}" >> "${logfile}.${test_number}" 2>&1 || return $?
889 check_written $((jobs * zone_size)) || return $?
890}
891
892# Random reads and writes across the entire disk for 30s.
893test30() {
894 local off
895
b34eb155 896 prep_write
191d1d1a 897 off=$((first_sequential_zone_sector * 512))
6dcb098d 898 run_one_fio_job "$(ioengine "libaio")" --iodepth=8 --rw=randrw \
79201772 899 --bs="$(max $((zone_size / 128)) "$min_seq_write_size")"\
191d1d1a
BVA
900 --zonemode=zbd --zonesize="${zone_size}" --offset=$off\
901 --loops=2 --time_based --runtime=30s --norandommap=1\
902 >>"${logfile}.${test_number}" 2>&1
903}
904
905# Random reads across all sequential zones for 30s. This is not only a fio
906# test but also allows to verify the performance of a drive.
907test31() {
908 local bs inc nz off opts size
909
40d0b842
SK
910 [ -n "$is_zbd" ] && reset_zone "$dev" -1
911
912 # As preparation, write 128 KB to sequential write required zones. Limit
913 # write target zones up to max_open_zones to keep test time reasonable.
914 # To distribute the write target zones evenly, skip certain zones for every
915 # write. Utilize zonemode strided for such write patterns.
916 bs=$((128 * 1024))
3ed8eea0
SK
917 off=$((first_sequential_zone_sector * 512))
918 size=$((disk_size - off))
f6e84423
DF
919 nz=$((max_open_zones))
920 if [[ $nz -eq 0 ]]; then
921 nz=128
922 fi
3ed8eea0
SK
923 if ((size / zone_size < nz)); then
924 nz=$((size / zone_size))
925 fi
40d0b842
SK
926 inc=$(((size / nz / zone_size) * zone_size))
927 opts=("--name=$dev" "--filename=$dev" "--rw=write" "--bs=${bs}")
928 opts+=("--offset=$off" "--size=$((inc * nz))" "--io_size=$((bs * nz))")
929 opts+=("--zonemode=strided" "--zonesize=${bs}" "--zonerange=${inc}")
4c99637e 930 opts+=("--direct=1" "$(ioengine "psync")")
40d0b842 931 echo "fio ${opts[@]}" >> "${logfile}.${test_number}"
4c99637e
SK
932 "$(dirname "$0")/../../fio" "${opts[@]}" >> "${logfile}.${test_number}" \
933 2>&1 || return $?
40d0b842
SK
934
935 # Next, run the test.
191d1d1a 936 opts=("--name=$dev" "--filename=$dev" "--offset=$off" "--size=$size")
6dcb098d 937 opts+=("--bs=$bs" "$(ioengine "psync")" "--rw=randread" "--direct=1")
191d1d1a
BVA
938 opts+=("--thread=1" "--time_based" "--runtime=30" "--zonemode=zbd")
939 opts+=("--zonesize=${zone_size}")
7ce7422a 940 opts+=(${job_var_opts[@]})
191d1d1a
BVA
941 run_fio "${opts[@]}" >> "${logfile}.${test_number}" 2>&1 || return $?
942}
943
944# Random writes across all sequential zones. This is not only a fio test but
945# also allows to verify the performance of a drive.
946test32() {
947 local off opts=() size
948
d480b019
SK
949 require_zbd || return $SKIP_TESTCASE
950
5b4c9c4e
SK
951 [ -n "$is_zbd" ] && reset_zone "$dev" -1
952
191d1d1a
BVA
953 off=$((first_sequential_zone_sector * 512))
954 size=$((disk_size - off))
955 opts+=("--name=$dev" "--filename=$dev" "--offset=$off" "--size=$size")
6dcb098d 956 opts+=("--bs=128K" "$(ioengine "psync")" "--rw=randwrite" "--direct=1")
191d1d1a
BVA
957 opts+=("--thread=1" "--time_based" "--runtime=30")
958 opts+=("--max_open_zones=$max_open_zones" "--zonemode=zbd")
959 opts+=("--zonesize=${zone_size}")
960 run_fio "${opts[@]}" >> "${logfile}.${test_number}" 2>&1 || return $?
961}
962
963# Write to sequential zones with a block size that is not a divisor of the
964# zone size.
965test33() {
966 local bs io_size size
d7c7539f 967 local off capacity=0;
191d1d1a 968
268b19c6
SK
969 [ -n "$is_zbd" ] && reset_zone "$dev" -1
970
d7c7539f
HH
971 off=$((first_sequential_zone_sector * 512))
972 capacity=$(total_zone_capacity 1 $off $dev)
191d1d1a 973 size=$((2 * zone_size))
d7c7539f
HH
974 io_size=$((5 * capacity))
975 bs=$((3 * capacity / 4))
6dcb098d
DF
976 run_fio_on_seq "$(ioengine "psync")" --iodepth=1 --rw=write \
977 --size=$size --io_size=$io_size --bs=$bs \
191d1d1a 978 >> "${logfile}.${test_number}" 2>&1 || return $?
268b19c6 979 check_written $((io_size / bs * bs)) || return $?
191d1d1a
BVA
980}
981
77789640 982# Test repeated async write job with verify using two unaligned block sizes.
191d1d1a 983test34() {
77789640
SK
984 local bs off zone_capacity
985 local -a block_sizes
986
987 require_zbd || return $SKIP_TESTCASE
988 prep_write
989
990 off=$((first_sequential_zone_sector * 512))
991 zone_capacity=$(total_zone_capacity 1 $off $dev)
992 block_sizes=($((4096 * 7)) $(($(min ${zone_capacity} 4194304) - 4096)))
993
994 for bs in ${block_sizes[@]}; do
995 run_fio --name=job --filename="${dev}" --rw=randwrite \
996 --bs="${bs}" --offset="${off}" \
997 --size=$((4 * zone_size)) --iodepth=256 \
998 "$(ioengine "libaio")" --time_based=1 --runtime=15s \
999 --zonemode=zbd --direct=1 --zonesize="${zone_size}" \
1000 --verify=crc32c --do_verify=1 ${job_var_opts[@]} \
1001 >> "${logfile}.${test_number}" 2>&1 || return $?
1002 done
191d1d1a
BVA
1003}
1004
1005# Test 1/4 for the I/O boundary rounding code: $size < $zone_size.
1006test35() {
1007 local bs off io_size size
1008
b34eb155 1009 prep_write
191d1d1a
BVA
1010 off=$(((first_sequential_zone_sector + 1) * 512))
1011 size=$((zone_size - 2 * 512))
1012 bs=$((zone_size / 4))
6dcb098d
DF
1013 run_one_fio_job --offset=$off --size=$size "$(ioengine "psync")" \
1014 --iodepth=1 --rw=write --do_verify=1 --verify=md5 \
1015 --bs=$bs --zonemode=zbd --zonesize="${zone_size}" \
191d1d1a
BVA
1016 >> "${logfile}.${test_number}" 2>&1 && return 1
1017 grep -q 'io_size must be at least one zone' "${logfile}.${test_number}"
1018}
1019
1020# Test 2/4 for the I/O boundary rounding code: $size < $zone_size.
1021test36() {
1022 local bs off io_size size
1023
b34eb155 1024 prep_write
191d1d1a
BVA
1025 off=$(((first_sequential_zone_sector) * 512))
1026 size=$((zone_size - 512))
1027 bs=$((zone_size / 4))
6dcb098d
DF
1028 run_one_fio_job --offset=$off --size=$size "$(ioengine "psync")" \
1029 --iodepth=1 --rw=write --do_verify=1 --verify=md5 \
1030 --bs=$bs --zonemode=zbd --zonesize="${zone_size}" \
191d1d1a
BVA
1031 >> "${logfile}.${test_number}" 2>&1 && return 1
1032 grep -q 'io_size must be at least one zone' "${logfile}.${test_number}"
1033}
1034
1035# Test 3/4 for the I/O boundary rounding code: $size > $zone_size.
1036test37() {
d7c7539f 1037 local bs off size capacity
191d1d1a 1038
b34eb155 1039 prep_write
cdf2f9e3 1040 capacity=$(total_zone_capacity 1 $((first_sequential_zone_sector*512)) $dev)
191d1d1a
BVA
1041 if [ "$first_sequential_zone_sector" = 0 ]; then
1042 off=0
1043 else
1044 off=$(((first_sequential_zone_sector - 1) * 512))
1045 fi
1046 size=$((zone_size + 2 * 512))
1ae82d67 1047 bs=$(min $((zone_size / 4)) "$zone_cap_bs")
6dcb098d
DF
1048 run_one_fio_job --offset=$off --size=$size "$(ioengine "psync")" \
1049 --iodepth=1 --rw=write --do_verify=1 --verify=md5 \
1050 --bs=$bs --zonemode=zbd --zonesize="${zone_size}" \
191d1d1a 1051 >> "${logfile}.${test_number}" 2>&1
d7c7539f 1052 check_written $capacity || return $?
191d1d1a
BVA
1053}
1054
1055# Test 4/4 for the I/O boundary rounding code: $offset > $disk_size - $zone_size
1056test38() {
1057 local bs off size
1058
b34eb155 1059 prep_write
79201772
SK
1060 size=$((min_seq_write_size))
1061 off=$((disk_size - min_seq_write_size))
1062 bs=$((min_seq_write_size))
6dcb098d
DF
1063 run_one_fio_job --offset=$off --size=$size "$(ioengine "psync")" \
1064 --iodepth=1 --rw=write --do_verify=1 --verify=md5 \
1065 --bs=$bs --zonemode=zbd --zonesize="${zone_size}" \
191d1d1a
BVA
1066 >> "${logfile}.${test_number}" 2>&1 && return 1
1067 grep -q 'io_size must be at least one zone' "${logfile}.${test_number}"
1068}
1069
1070# Read one block from a block device.
1071read_one_block() {
c6950209 1072 local off
191d1d1a
BVA
1073 local bs
1074
c6950209
DF
1075 if ! result=($(first_online_zone "$dev")); then
1076 echo "Failed to determine first online zone"
1077 exit 1
1078 fi
1079 off=${result[0]}
79201772 1080 bs=$((min_seq_write_size))
c6950209
DF
1081 run_one_fio_job --rw=read "$(ioengine "psync")" --offset=$off --bs=$bs \
1082 --size=$bs "$@" 2>&1 |
191d1d1a
BVA
1083 tee -a "${logfile}.${test_number}"
1084}
1085
1086# Check whether fio accepts --zonemode=none for zoned block devices.
1087test39() {
d480b019 1088 require_zbd || return $SKIP_TESTCASE
191d1d1a 1089 read_one_block --zonemode=none >/dev/null || return $?
79201772 1090 check_read $((min_seq_write_size)) || return $?
191d1d1a
BVA
1091}
1092
1093# Check whether fio accepts --zonemode=strided for zoned block devices.
1094test40() {
1095 local bs
1096
79201772 1097 bs=$((min_seq_write_size))
d480b019 1098 require_zbd || return $SKIP_TESTCASE
191d1d1a
BVA
1099 read_one_block --zonemode=strided |
1100 grep -q 'fio: --zonesize must be specified when using --zonemode=strided' ||
1101 return $?
1102 read_one_block --zonemode=strided --zonesize=$bs >/dev/null || return $?
1103 check_read $bs || return $?
1104}
1105
1106# Check whether fio checks the zone size for zoned block devices.
1107test41() {
d480b019 1108 require_zbd || return $SKIP_TESTCASE
191d1d1a
BVA
1109 read_one_block --zonemode=zbd --zonesize=$((2 * zone_size)) |
1110 grep -q 'job parameter zonesize.*does not match disk zone size'
1111}
1112
1113# Check whether fio handles --zonesize=0 correctly for regular block devices.
1114test42() {
d480b019 1115 require_regular_block_dev || return $SKIP_TESTCASE
191d1d1a 1116 read_one_block --zonemode=zbd --zonesize=0 |
a59b12d2 1117 grep -q 'Specifying the zone size is mandatory for regular file/block device with --zonemode=zbd'
191d1d1a
BVA
1118}
1119
a4b7f12b 1120# Check whether fio handles --zonesize=1 correctly for regular block devices.
191d1d1a 1121test43() {
d480b019 1122 require_regular_block_dev || return $SKIP_TESTCASE
191d1d1a
BVA
1123 read_one_block --zonemode=zbd --zonesize=1 |
1124 grep -q 'zone size must be at least 512 bytes for --zonemode=zbd'
1125}
1126
1127# Check whether fio handles --zonemode=none --zonesize=1 correctly.
1128test44() {
1129 read_one_block --zonemode=none --zonesize=1 |
1130 grep -q 'fio: --zonemode=none and --zonesize are not compatible'
1131}
1132
1133test45() {
1134 local bs i
50b94305 1135 local grep_str="fio: first I/O failed. If .* is a zoned block device, consider --zonemode=zbd"
191d1d1a 1136
d480b019 1137 require_zbd || return $SKIP_TESTCASE
b34eb155 1138 prep_write
79201772 1139 bs=$((min_seq_write_size))
50b94305
SK
1140 for ((i = 0; i < 10; i++)); do
1141 run_one_fio_job "$(ioengine "psync")" --iodepth=1 --rw=randwrite \
1142 --offset=$((first_sequential_zone_sector * 512)) \
1143 --bs="$bs" --time_based --runtime=1s \
1144 --do_verify=1 --verify=md5 \
1145 >> "${logfile}.${test_number}" 2>&1
1146 grep -qe "$grep_str" "${logfile}.${test_number}" && return 0
1147 done
1148 return 1
191d1d1a
BVA
1149}
1150
bc596cbc
DLM
1151# Random write to sequential zones, libaio, 8 jobs, queue depth 64 per job
1152test46() {
1153 local size
1154
b34eb155 1155 prep_write
bc596cbc 1156 size=$((4 * zone_size))
6dcb098d 1157 run_fio_on_seq "$(ioengine "libaio")" --iodepth=64 --rw=randwrite --bs=4K \
bc596cbc
DLM
1158 --group_reporting=1 --numjobs=8 \
1159 >> "${logfile}.${test_number}" 2>&1 || return $?
1160 check_written $((size * 8)) || return $?
1161}
1162
4d37720a
DLM
1163# Check whether fio handles --zonemode=zbd --zoneskip=1 correctly.
1164test47() {
1165 local bs
1166
b34eb155 1167 prep_write
79201772 1168 bs=$((min_seq_write_size))
e0424151 1169 run_fio_on_seq "$(ioengine "psync")" --rw=write --bs=$bs --zoneskip=1 \
4d37720a
DLM
1170 >> "${logfile}.${test_number}" 2>&1 && return 1
1171 grep -q 'zoneskip 1 is not a multiple of the device zone size' "${logfile}.${test_number}"
1172}
1173
3bd2078b
NA
1174# Multiple overlapping random write jobs for the same drive and with a
1175# limited number of open zones. This is similar to test29, but uses libaio
1176# to stress test zone locking.
1177test48() {
1178 local i jobs=16 off opts=()
1179
d480b019 1180 require_zbd || return $SKIP_TESTCASE
1200ac6a 1181 require_seq_zones 80 || return $SKIP_TESTCASE
d480b019 1182
3bd2078b
NA
1183 off=$((first_sequential_zone_sector * 512 + 64 * zone_size))
1184 size=$((16*zone_size))
5b4c9c4e
SK
1185
1186 [ -n "$is_zbd" ] && reset_zone "$dev" -1
1187
3bd2078b
NA
1188 opts=("--aux-path=/tmp" "--allow_file_create=0" "--significant_figures=10")
1189 opts+=("--debug=zbd")
6dcb098d 1190 opts+=("$(ioengine "libaio")" "--rw=randwrite" "--direct=1")
3bd2078b
NA
1191 opts+=("--time_based" "--runtime=30")
1192 opts+=("--zonemode=zbd" "--zonesize=${zone_size}")
1193 opts+=("--max_open_zones=4")
1194 for ((i=0;i<jobs;i++)); do
1195 opts+=("--name=job$i" "--filename=$dev" "--offset=$off" "--bs=16K")
1196 opts+=("--io_size=$zone_size" "--iodepth=256" "--thread=1")
8c17a624 1197 opts+=("--size=$size" "--group_reporting=1")
7ce7422a
SK
1198 # max_open_zones is already specified
1199 opts+=($(job_var_opts_exclude "--max_open_zones"))
3bd2078b
NA
1200 done
1201
1202 fio=$(dirname "$0")/../../fio
1203
1204 { echo; echo "fio ${opts[*]}"; echo; } >>"${logfile}.${test_number}"
1205
b13fd959 1206 timeout -v -s KILL 180s \
3bd2078b
NA
1207 "${dynamic_analyzer[@]}" "$fio" "${opts[@]}" \
1208 >> "${logfile}.${test_number}" 2>&1 || return $?
1209}
1210
5c0400e7
HH
1211# Check if fio handles --zonecapacity on a normal block device correctly
1212test49() {
1213
d480b019 1214 require_regular_block_dev || return $SKIP_TESTCASE
5c0400e7
HH
1215
1216 size=$((2 * zone_size))
1217 capacity=$((zone_size * 3 / 4))
1218
1219 run_one_fio_job "$(ioengine "psync")" --rw=write \
1220 --zonemode=zbd --zonesize="${zone_size}" \
1221 --zonecapacity=${capacity} \
1222 --verify=md5 --size=${size} >>"${logfile}.${test_number}" 2>&1 ||
1223 return $?
693403eb 1224 check_written $((capacity * 2)) || return $?
5c0400e7
HH
1225 check_read $((capacity * 2)) || return $?
1226}
1227
a66a8fab
SK
1228# Verify that conv zones are not locked and only seq zones are locked during
1229# random read on conv-seq mixed zones.
1230test50() {
1231 local off
1232
1233 require_zbd || return $SKIP_TESTCASE
1234 require_conv_zones 8 || return $SKIP_TESTCASE
1235 require_seq_zones 8 || return $SKIP_TESTCASE
1236
1237 reset_zone "${dev}" -1
1238
1239 off=$((first_sequential_zone_sector * 512 - 8 * zone_size))
1240 run_fio --name=job --filename=${dev} --offset=${off} --bs=64K \
1241 --size=$((16 * zone_size)) "$(ioengine "libaio")" --rw=randread\
1242 --time_based --runtime=3 --zonemode=zbd --zonesize=${zone_size}\
1243 --direct=1 --group_reporting=1 ${job_var_opts[@]} \
1244 >> "${logfile}.${test_number}" 2>&1 || return $?
1245}
1246
1247# Verify that conv zones are neither locked nor opened during random write on
1248# conv-seq mixed zones. Zone lock and zone open shall happen only on seq zones.
1249test51() {
1250 local off jobs=16
1251 local -a opts
1252
1253 require_zbd || return $SKIP_TESTCASE
1254 require_conv_zones 8 || return $SKIP_TESTCASE
1255 require_seq_zones 8 || return $SKIP_TESTCASE
1256
5b4c9c4e 1257 reset_zone "$dev" -1
a66a8fab
SK
1258
1259 off=$((first_sequential_zone_sector * 512 - 8 * zone_size))
1260 opts+=("--size=$((16 * zone_size))" "$(ioengine "libaio")")
1261 opts+=("--zonemode=zbd" "--direct=1" "--zonesize=${zone_size}")
1262 opts+=("--max_open_zones=2" "--offset=$off")
1263 opts+=("--thread=1" "--group_reporting=1")
1264 opts+=("--time_based" "--runtime=30" "--rw=randwrite")
1265 for ((i=0;i<jobs;i++)); do
1266 opts+=("--name=job${i}" "--filename=$dev")
1267 opts+=("--bs=$(((i+1)*16))K")
1268 opts+=($(job_var_opts_exclude "--max_open_zones"))
1269 done
1270 run_fio "${opts[@]}" >> "${logfile}.${test_number}" 2>&1 || return $?
1271}
1272
d56a6df3
SK
1273# Verify that zone_reset_threshold only accounts written bytes in seq
1274# zones, and written data bytes of conv zones are not counted.
d93379d7
SK
1275test52() {
1276 local off io_size
1277
1278 require_zbd || return $SKIP_TESTCASE
1279 require_conv_zones 8 || return $SKIP_TESTCASE
1280 require_seq_zones 8 || return $SKIP_TESTCASE
1281
1282 reset_zone "${dev}" -1
1283
1284 # Total I/O size is 1/8 = 0.125 of the I/O range of cont + seq zones.
1285 # Set zone_reset_threshold as 0.1. The threshold size is less than
1286 # 0.125, then, reset count zero is expected.
1287 # On the other hand, half of the I/O range is covered by conv zones.
1288 # If fio would count the conv zones for zone_reset_threshold, the ratio
1289 # were more than 0.5 and would trigger zone resets.
1290
1291 off=$((first_sequential_zone_sector * 512 - 8 * zone_size))
1292 io_size=$((zone_size * 16 / 8))
1293 run_fio --name=job --filename=$dev --rw=randwrite --bs=$((zone_size/16))\
1294 --size=$((zone_size * 16)) --softrandommap=1 \
1295 --io_size=$((io_size)) "$(ioengine "psync")" --offset=$off \
1296 --zonemode=zbd --direct=1 --zonesize=${zone_size} \
1297 --zone_reset_threshold=.1 --zone_reset_frequency=1.0 \
1298 ${job_var_opts[@]} --debug=zbd \
1299 >> "${logfile}.${test_number}" 2>&1 || return $?
1300
1301 check_written ${io_size} || return $?
1302 check_reset_count -eq 0 || return $?
1303}
1304
9ffe8f1b
SK
1305# Check both reads and writes are executed by random I/O to conventional zones.
1306test53() {
1307 local off capacity io read_b=0 written_b=0
1308
1309 require_zbd || return $SKIP_TESTCASE
1310 require_conv_zones 4 || return $SKIP_TESTCASE
1311
1312 off=$((first_sequential_zone_sector * 512 - 4 * zone_size))
1313 capacity=$(total_zone_capacity 4 $off $dev)
1314 run_fio --name=job --filename=${dev} --rw=randrw --bs=64K \
1315 --size=$((4 * zone_size)) "$(ioengine "psync")" --offset=${off}\
1316 --zonemode=zbd --direct=1 --zonesize=${zone_size} \
1317 ${job_var_opts[@]} \
1318 >> "${logfile}.${test_number}" 2>&1 || return $?
1319
1320 written_b=$(fio_written <"${logfile}.${test_number}")
1321 read_b=$(fio_read <"${logfile}.${test_number}")
1322 io=$((written_b + read_b))
1323 echo "Number of bytes read: $read_b" >>"${logfile}.${test_number}"
1324 echo "Number of bytes written: $written_b" >>"${logfile}.${test_number}"
1325 echo "Total number of bytes read and written: $io <> $capacity" \
1326 >>"${logfile}.${test_number}"
1327 if ((io==capacity && written_b != 0 && read_b != 0)); then
1328 return 0
1329 fi
1330 return 1
1331}
1332
7def9723
DF
1333# Test read/write mix with verify.
1334test54() {
1335 require_zbd || return $SKIP_TESTCASE
1336 require_seq_zones 8 || return $SKIP_TESTCASE
1337
4f9333c9 1338 prep_write
7def9723
DF
1339 run_fio --name=job --filename=${dev} "$(ioengine "libaio")" \
1340 --time_based=1 --runtime=30s --continue_on_error=0 \
1341 --offset=$((first_sequential_zone_sector * 512)) \
1342 --size=$((8*zone_size)) --direct=1 --iodepth=1 \
1343 --rw=randrw:2 --rwmixwrite=25 --bsrange=4k-${zone_size} \
1344 --zonemode=zbd --zonesize=${zone_size} \
1345 --verify=crc32c --do_verify=1 --verify_backlog=2 \
7def9723
DF
1346 --alloc-size=65536 --random_generator=tausworthe64 \
1347 ${job_var_opts[@]} --debug=zbd \
8f39afa7
AD
1348 >> "${logfile}.${test_number}" 2>&1 || return $?
1349}
1350
1351# test 'z' suffix parsing only
1352test55() {
1353 local bs
79201772 1354 bs=$((min_seq_write_size))
8f39afa7
AD
1355
1356 require_zbd || return $SKIP_TESTCASE
1357 # offset=1z + offset_increment=10z + size=2z
1358 require_seq_zones 13 || return $SKIP_TESTCASE
1359
4f9333c9 1360 prep_write
8f39afa7
AD
1361 run_fio --name=j \
1362 --filename=${dev} \
1363 --direct=1 \
1364 "$(ioengine "psync")" \
1365 --zonemode=zbd \
1366 --zonesize=${zone_size} \
1367 --rw=write \
1368 --bs=${bs} \
1369 --numjobs=2 \
1370 --offset_increment=10z \
1371 --offset=1z \
1372 --size=2z \
1373 --io_size=3z \
1374 ${job_var_opts[@]} --debug=zbd \
1375 >> "${logfile}.${test_number}" 2>&1 || return $?
1376}
1377
1378# test 'z' suffix parsing only
1379test56() {
1380 local bs
79201772 1381 bs=$((min_seq_write_size))
8f39afa7
AD
1382
1383 require_regular_block_dev || return $SKIP_TESTCASE
1384 require_seq_zones 10 || return $SKIP_TESTCASE
1385
4f9333c9 1386 prep_write
8f39afa7
AD
1387 run_fio --name=j \
1388 --filename=${dev} \
1389 --direct=1 \
1390 "$(ioengine "psync")" \
1391 --zonemode=strided \
1392 --zonesize=${zone_size} \
1393 --rw=write \
1394 --bs=${bs} \
1395 --size=10z \
1396 --zoneskip=2z \
1397 ${job_var_opts[@]} --debug=zbd \
7def9723
DF
1398 >> "${logfile}.${test_number}" 2>&1 || return $?
1399}
1400
9b6253bc
SK
1401# Test that repeated async write job does not cause zone reset during writes
1402# in-flight, when the block size is not a divisor of the zone size.
1403test57() {
1404 local bs off
1405
1406 require_zbd || return $SKIP_TESTCASE
1407
4f9333c9 1408 prep_write
9b6253bc
SK
1409 bs=$((4096 * 7))
1410 off=$((first_sequential_zone_sector * 512))
1411
1412 run_fio --name=job --filename="${dev}" --rw=randwrite --bs="${bs}" \
1413 --offset="${off}" --size=$((4 * zone_size)) --iodepth=256 \
1414 "$(ioengine "libaio")" --time_based=1 --runtime=30s \
1415 --zonemode=zbd --direct=1 --zonesize="${zone_size}" \
1416 ${job_var_opts[@]} \
1417 >> "${logfile}.${test_number}" 2>&1 || return $?
1418}
1419
faff87e6
SK
1420# Random writes and random trims to sequential write required zones for 30s.
1421test58() {
1422 local off size bs
1423
1424 require_seq_zones 128 || return $SKIP_TESTCASE
1425
1426 size=$((zone_size * 128))
79201772 1427 bs="$(max $((zone_size / 128)) "$min_seq_write_size")"
faff87e6
SK
1428 prep_write
1429 off=$((first_sequential_zone_sector * 512))
1430 run_fio --zonemode=zbd --direct=1 --zonesize="${zone_size}" --thread=1 \
1431 --filename="${dev}" --norandommap=1 \
1432 --name="precondition" --rw=write "$(ioengine "psync")" \
1433 --offset="${off}" --size=$((zone_size * 16)) --bs="${bs}" \
1434 "${job_var_opts[@]}" \
1435 --name=wjob --wait_for="precondition" --rw=randwrite \
1436 "$(ioengine "libaio")" --iodepth=8 \
1437 --offset="${off}" --size="${size}" --bs="${bs}" \
1438 --time_based --runtime=30s --flow=128 "${job_var_opts[@]}" \
1439 --name=trimjob --wait_for="precondition" --rw=randtrim \
1440 "$(ioengine "psync")" \
1441 --offset="${off}" --size="${size}" --bs="${zone_size}" \
1442 --time_based --runtime=30s --flow=1 "${job_var_opts[@]}" \
1443 >>"${logfile}.${test_number}" 2>&1
1444}
1445
7b6db712
SK
1446# Test zone_reset_threshold with verify.
1447test59() {
1448 local off bs loops=2 size=$((zone_size)) w
1449 local -a workloads=(write randwrite rw randrw)
1450
1451 prep_write
1452 off=$((first_sequential_zone_sector * 512))
1453
1454 bs=$(min $((256*1024)) "$zone_size")
1455 for w in "${workloads[@]}"; do
1456 run_fio_on_seq "$(ioengine "psync")" --rw=${w} --bs="$bs" \
1457 --size=$size --loops=$loops --do_verify=1 \
1458 --verify=md5 --zone_reset_frequency=.9 \
1459 --zone_reset_threshold=.1 \
1460 >> "${logfile}.${test_number}" 2>&1 || return $?
1461 done
1462}
1463
78054a76
SK
1464# Test fio errors out experimental_verify option with zonemode=zbd.
1465test60() {
1466 run_fio_on_seq "$(ioengine "psync")" --rw=write --size=$zone_size \
1467 --do_verify=1 --verify=md5 --experimental_verify=1 \
1468 >> "${logfile}.${test_number}" 2>&1 && return 1
1469 grep -q 'not support experimental verify' "${logfile}.${test_number}"
1470}
1471
e31c83cb
SK
1472# Test fio errors out zone_reset_threshold option for multiple jobs with
1473# different write ranges.
1474test61() {
1475 run_fio_on_seq "$(ioengine "psync")" --rw=write --size="$zone_size" \
1476 --numjobs=2 --offset_increment="$zone_size" \
1477 --zone_reset_threshold=0.1 --zone_reset_frequency=1 \
1478 --exitall_on_error=1 \
1479 >> "${logfile}.${test_number}" 2>&1 && return 1
1480 grep -q 'different write ranges' "${logfile}.${test_number}"
1481}
1482
1483# Test zone_reset_threshold option works for multiple jobs with same write
1484# range.
1485test62() {
1486 local bs loops=2 size=$((zone_size))
1487
1488 [ -n "$is_zbd" ] && reset_zone "$dev" -1
1489
1490 # Two jobs write to single zone twice. Reset zone happens at next write
1491 # after half of the zone gets filled. So 2 * 2 * 2 - 1 = 7 times zone
1492 # resets are expected.
1493 bs=$(min $((256*1024)) $((zone_size / 4)))
1494 run_fio_on_seq "$(ioengine "psync")" --rw=write --bs="$bs" \
1495 --size=$size --loops=$loops --numjobs=2 \
1496 --zone_reset_frequency=1 --zone_reset_threshold=.5 \
1497 --group_reporting=1 \
1498 >> "${logfile}.${test_number}" 2>&1 || return $?
1499 check_written $((size * loops * 2)) || return $?
1500 check_reset_count -eq 7 || return $?
1501}
1502
1503# Test zone_reset_threshold option works for a read job and a write job with
1504# different IO range.
1505test63() {
1506 local bs loops=2 size=$((zone_size)) off1 off2
1507
1508 [ -n "$is_zbd" ] && reset_zone "$dev" -1
1509
1510 off1=$((first_sequential_zone_sector * 512))
1511 off2=$((off1 + zone_size))
1512 bs=$(min $((256*1024)) $((zone_size / 4)))
1513
1514 # One job writes to single zone twice. Reset zone happens at next write
1515 # after half of the zone gets filled. So 2 * 2 - 1 = 3 times zone resets
1516 # are expected.
1517 run_fio "$(ioengine "psync")" --bs="$bs" --size=$size --loops=$loops \
1518 --filename="$dev" --group_reporting=1 \
1519 --zonemode=zbd --zonesize="$zone_size" --direct=1 \
1520 --zone_reset_frequency=1 --zone_reset_threshold=.5 \
1521 --name=r --rw=read --offset=$off1 "${job_var_opts[@]}" \
1522 --name=w --rw=write --offset=$off2 "${job_var_opts[@]}" \
1523 >> "${logfile}.${test_number}" 2>&1 || return $?
1524 check_written $((size * loops)) || return $?
1525 check_reset_count -eq 3 || return $?
1526}
1527
2495bcd8
SK
1528# Test write zone accounting handles almost full zones correctly. Prepare an
1529# almost full, but not full zone. Write to the zone with verify using larger
1530# block size. Then confirm fio does not report write zone accounting failure.
1531test64() {
1532 local bs cap
1533
1534 [ -n "$is_zbd" ] && reset_zone "$dev" -1
1535
1536 bs=$((zone_size / 8))
1537 cap=$(total_zone_capacity 1 $((first_sequential_zone_sector*512)) $dev)
1538 run_fio_on_seq "$(ioengine "psync")" --rw=write --bs="$bs" \
1539 --size=$((zone_size)) \
1540 --io_size=$((cap - bs)) \
1541 >> "${logfile}.${test_number}" 2>&1 || return $?
1542
1543 bs=$((zone_size / 2))
1544 run_fio_on_seq "$(ioengine "psync")" --rw=write --bs="$bs" \
1545 --size=$((zone_size)) --do_verify=1 --verify=md5 \
1546 >> "${logfile}.${test_number}" 2>&1 || return $?
1547}
1548
edaee5b9
SK
1549# Test open zone accounting handles trim workload correctly. Prepare open zones
1550# as many as max_open_zones=4. Trim one of the 4 zones. Then write to another
1551# zone and check the write amount is expected size.
1552test65() {
1553 local off capacity
1554
1555 [ -n "$is_zbd" ] && reset_zone "$dev" -1
1556
1557 off=$((first_sequential_zone_sector * 512))
1558 capacity=$(total_zone_capacity 1 $off "$dev")
1559 run_fio --zonemode=zbd --direct=1 --zonesize="$zone_size" --thread=1 \
1560 --filename="$dev" --group_reporting=1 --max_open_zones=4 \
1561 "$(ioengine "psync")" \
1562 --name="prep_open_zones" --rw=randwrite --offset="$off" \
1563 --size="$((zone_size * 4))" --bs=4096 --io_size="$zone_size" \
1564 --name=trimjob --wait_for="prep_open_zones" --rw=trim \
1565 --bs="$zone_size" --offset="$off" --size="$zone_size" \
1566 --name=write --wait_for="trimjob" --rw=write --bs=4096 \
1567 --offset="$((off + zone_size * 4))" --size="$zone_size" \
1568 >> "${logfile}.${test_number}" 2>&1
1569
1570 check_written $((zone_size + capacity))
1571}
1572
b3be0f00
SK
1573# Test closed zones are handled as open zones. This test case requires zoned
1574# block devices which has same max_open_zones and max_active_zones.
1575test66() {
1576 local i off
1577
1578 require_zbd || return $SKIP_TESTCASE
1579 require_max_active_zones 2 || return $SKIP_TESTCASE
1580 require_max_open_zones "${max_active_zones}" || return $SKIP_TESTCASE
1581 require_seq_zones $((max_active_zones * 16)) || return $SKIP_TESTCASE
1582
1583 reset_zone "$dev" -1
1584
1585 # Prepare max_active_zones in closed condition.
1586 off=$((first_sequential_zone_sector * 512))
1587 run_fio --name=w --filename="$dev" --zonemod=zbd --direct=1 \
1588 --offset=$((off)) --zonesize="${zone_size}" --rw=randwrite \
1589 --bs=4096 --size="$((zone_size * max_active_zones))" \
1590 --io_size="${zone_size}" "$(ioengine "psync")" \
1591 >> "${logfile}.${test_number}" 2>&1 || return $?
1592 for ((i = 0; i < max_active_zones; i++)); do
1593 close_zone "$dev" $((off / 512)) || return $?
1594 off=$((off + zone_size))
1595 done
1596
1597 # Run random write to the closed zones and empty zones. This confirms
1598 # that fio handles closed zones as write target open zones. Otherwise,
1599 # fio writes to the empty zones and hit the max_active_zones limit.
1600 off=$((first_sequential_zone_sector * 512))
1601 run_one_fio_job --zonemod=zbd --direct=1 \
1602 "$(ioengine "psync")" --rw=randwrite --bs=4096 \
1603 --max_open_zones="$max_active_zones" --offset=$((off)) \
1604 --size=$((max_active_zones * 16 * zone_size)) \
1605 --io_size=$((zone_size)) --zonesize="${zone_size}" \
1606 --time_based --runtime=5s \
1607 >> "${logfile}.${test_number}" 2>&1
1608}
1609
25868b05
SK
1610# Test max_active_zones limit failure is reported with good error message.
1611test67() {
1612 local i off
1613
1614 require_zbd || return $SKIP_TESTCASE
1615 require_max_active_zones 2 || return $SKIP_TESTCASE
1616 require_max_open_zones "${max_active_zones}" || return $SKIP_TESTCASE
1617 require_seq_zones $((max_active_zones + 1)) || return $SKIP_TESTCASE
1618
1619 reset_zone "$dev" -1
1620
1621 # Prepare max_active_zones in open condition.
1622 off=$((first_sequential_zone_sector * 512))
1623 run_fio --name=w --filename="$dev" --zonemod=zbd --direct=1 \
1624 --offset=$((off)) --zonesize="${zone_size}" --rw=randwrite \
1625 --bs=4096 --size="$((zone_size * max_active_zones))" \
1626 --io_size="${zone_size}" "$(ioengine "psync")" \
1627 >> "${logfile}.${test_number}" 2>&1 || return $?
1628
1629 # Write to antoher zone and trigger max_active_zones limit error.
1630 off=$((off + zone_size * max_active_zones))
1631 run_one_fio_job --zonemod=zbd --direct=1 "$(ioengine "psync")" \
1632 --rw=write --bs=$min_seq_write_size --offset=$((off)) \
1633 --size=$((zone_size)) --zonesize="${zone_size}" \
1634 >> "${logfile}.${test_number}" 2>&1 && return $?
1635 grep -q 'Exceeded max_active_zones limit' "${logfile}.${test_number}"
1636}
1637
be943a3e
SK
1638# Test rw=randrw and rwmixwrite=0 options do not issue write I/O unit
1639test68() {
1640 local off size
1641
1642 require_zbd || return "$SKIP_TESTCASE"
1643
1644 reset_zone "${dev}" -1
1645
1646 # Write some data as preparation
1647 off=$((first_sequential_zone_sector * 512))
1648 size=$min_seq_write_size
1649 run_one_fio_job "$(ioengine "psync")" --rw=write --offset="$off" \
1650 --io_size="$size" --zonemode=strided \
1651 --zonesize="$zone_size" --zonerange="$zone_size" \
1652 >> "${logfile}.${test_number}" 2>&1 || return $?
1653 # Run random mixed read and write specifying zero write ratio
1654 run_fio_on_seq "$(ioengine "psync")" --rw=randrw --rwmixwrite=0 \
1655 --time_based --runtime=1s \
1656 >> "${logfile}.${test_number}" 2>&1 || return $?
1657 # "WRITE:" shall be recoreded only once for the preparation
1658 [[ $(grep -c "WRITE:" "${logfile}.${test_number}") == 1 ]]
1659}
1660
06eb4c1f
SK
1661# Test rw=rw and verify_backlog=1 options do not cause verify failure
1662test69() {
1663 require_zbd || return "$SKIP_TESTCASE"
1664
1665 prep_write
1666 run_fio --name=job --filename="$dev" --time_based --runtime=15s \
1667 --rw=rw --offset=$((first_sequential_zone_sector * 512)) \
1668 "$(ioengine "libaio")" --iodepth=32 --randrepeat=0 \
1669 --verify=crc32 --verify_backlog=1 --zonemode=zbd --direct=1 \
1670 >> "${logfile}.${test_number}" 2>&1 || return $?
1671}
1672
0f754a3a
SK
1673# Test max_open_zones and job_max_open_zones do not error out for non-write jobs
1674test70() {
1675 require_zbd || return "$SKIP_TESTCASE"
1676
1677 reset_zone "${dev}" -1
1678
1679 # Write data to two zones and make them open
1680 run_fio_on_seq "$(ioengine "psync")" --io_size="$min_seq_write_size" \
1681 --rw=write --offset_increment=1z --numjobs=2 \
1682 --group_reporting=1 >> "${logfile}.${test_number}" 2>&1
1683
1684 # Confirm max_open_zones=1 for read workload does not fail
1685 run_fio_on_seq "$(ioengine "psync")" --io_size="$min_seq_write_size" \
1686 --rw=read --max_open_zones=1 \
1687 >> "${logfile}.${test_number}" 2>&1 || return $?
1688
1689 # Confirm job_max_open_zones=1 for read workload does not fail
1690 run_fio_on_seq "$(ioengine "psync")" --io_size="$min_seq_write_size" \
1691 --rw=read --job_max_open_zones=1 \
1692 >> "${logfile}.${test_number}" 2>&1
1693 grep -q 'valid only for write jobs' \
1694 "${logfile}.${test_number}" || return $?
1695
1696 # Confirm max_open_zones=1 for trim workload does not fail
1697 run_fio_on_seq "$(ioengine "psync")" --rw=trim --io_size=1z \
1698 --bs="$zone_size" --max_open_zones=1 \
1699 >> "${logfile}.${test_number}" 2>&1
1700}
1701
96afc233
SK
1702# Test random write does not end early when the zones as many as max_open_zones
1703# have remainder smaller than block size.
1704test71() {
1705 local off size capacity zone_fill_size i
1706
1707 require_zbd || return "$SKIP_TESTCASE"
1708 require_seq_zones 8 || return "$SKIP_TESTCASE"
1709 require_no_max_active_zones || return "$SKIP_TESTCASE"
1710
1711 reset_zone "${dev}" -1
1712
1713 # Fill data to every other zone in the test target 8 zones. This leaves
1714 # 4 zones in the implicit open condition. Leave 12kb remainder in the
1715 # 4 zones.
1716 off=$((first_sequential_zone_sector * 512))
1717 size=$min_seq_write_size
1718 capacity=$(total_zone_capacity 1 "$off" "$dev")
1719 zone_fill_size=$((capacity - 3 * 4096))
1720 run_one_fio_job "$(ioengine "psync")" --rw=write --offset="$off" \
1721 --bs=4k --zonemode=strided \
1722 --zonesize="$zone_fill_size" \
1723 --zonerange=$((zone_size * 2)) \
1724 --io_size=$((zone_fill_size * 4)) \
1725 >> "${logfile}.${test_number}" 2>&1 || return $?
1726 # Close the 4 zones to not fail the next fio command with the
1727 # --max_open_zones=1 option
1728 for ((i = 0; i < 4; i++)); do
1729 close_zone "$dev" $(((off + zone_size * 2 * i) / 512)) || return $?
1730 done
1731
1732 # Run random write with 8kb block size
1733 run_one_fio_job "$(ioengine "psync")" --rw=randwrite --offset="$off" \
1734 --bs=$((4096 * 2)) --zonemode=zbd \
1735 --zonesize="$zone_size" --size=$((zone_size * 8)) \
1736 --max_open_zones=1 --debug=zbd \
1737 >> "${logfile}.${test_number}" 2>&1 || return $?
1738
1739 check_written $((zone_size * 8)) || return $?
1740}
1741
b6002e78
SK
1742set_nullb_badblocks() {
1743 local syspath
1744
1745 syspath=/sys/kernel/config/nullb/"${dev##*/}"
1746 if [[ -w $syspath/badblocks ]]; then
1747 echo "$1" > "$syspath"/badblocks
1748 fi
1749
1750 return 0
1751}
1752
1753# The helper function to set up badblocks or error command and echo back
1754# number of expected failures. If the device is null_blk, set the errors
1755# at the sectors based of 1st argument (offset) and 2nd argument (gap).
1756# If the device is scsi_debug, set the first write commands to fail.
1757set_badblocks() {
1758 local off=$(($1 / 512))
1759 local gap=$(($2 / 512))
1760 local syspath block scsi_dev
1761
1762 # null_blk
1763 syspath=/sys/kernel/config/nullb/"${dev##*/}"
1764 if [[ -d ${syspath} ]]; then
1765 block=$((off + 2))
1766 set_nullb_badblocks "+${block}-${block}"
1767 block=$((off + gap + 11))
1768 set_nullb_badblocks "+${block}-${block}"
1769 block=$((off + gap*2 + 8))
1770 set_nullb_badblocks "+${block}-${block}"
1771
1772 echo 3
1773 return
1774 fi
1775
1776 # scsi_debug
1777 scsi_dev=$(get_scsi_device_path "$dev")
1778 syspath=/sys/kernel/debug/scsi_debug/"${scsi_dev##*/}"/
1779 echo 2 -1 0x8a 0x00 0x00 0x02 0x03 0x11 0x02 > "$syspath"/error
1780
1781 echo 1
1782}
1783
1784# Single job sequential sync write to sequential zones, with continue_on_error
1785test72() {
1786 local size off capacity bs expected_errors
1787
1788 require_zbd || return "$SKIP_TESTCASE"
1789 require_badblock || return "$SKIP_TESTCASE"
1790
1791 prep_write
1792 off=$((first_sequential_zone_sector * 512))
1793 bs=$(min "$(max $((zone_size / 64)) "$min_seq_write_size")" "$zone_cap_bs")
1794 expected_errors=$(set_badblocks "$off" "$zone_size")
1795 size=$((4 * zone_size))
1796 capacity=$((size - bs * expected_errors))
1797 run_fio_on_seq "$(ioengine "psync")" --rw=write --offset="$off" \
1798 --size="$size" --bs="$bs" --do_verify=1 --verify=md5 \
1799 --continue_on_error=1 --recover_zbd_write_error=1 \
1800 --ignore_error=,EIO:61 --debug=zbd \
1801 >>"${logfile}.${test_number}" 2>&1 || return $?
1802 check_written "$capacity" || return $?
1803 grep -qe "Write pointer move succeeded" "${logfile}.${test_number}"
1804}
1805
1806# Multi job sequential async write to sequential zones, with continue_on_error
1807test73() {
1808 local size off capacity bs
1809
1810 require_zbd || return "$SKIP_TESTCASE"
1811 require_badblock || return "$SKIP_TESTCASE"
1812
1813 prep_write
1814 off=$((first_sequential_zone_sector * 512))
1815 bs=$(min "$(max $((zone_size / 64)) "$min_seq_write_size")" "$zone_cap_bs")
1816 set_badblocks "$off" "$zone_size" > /dev/null
1817 capacity=$(total_zone_capacity 4 "$off" "$dev")
1818 size=$((zone_size * 4))
1819 run_fio --name=w --filename="${dev}" --rw=write "$(ioengine "libaio")" \
1820 --iodepth=32 --numjob=8 --group_reporting=1 --offset="$off" \
1821 --size="$size" --bs="$bs" --zonemode=zbd --direct=1 \
1822 --zonesize="$zone_size" --continue_on_error=1 \
1823 --recover_zbd_write_error=1 --debug=zbd \
1824 >>"${logfile}.${test_number}" 2>&1 || return $?
1825 grep -qe "Write pointer move succeeded" \
1826 "${logfile}.${test_number}"
1827}
1828
1829# Single job sequential sync write to sequential zones, with continue_on_error,
1830# with failures in the recovery writes.
1831test74() {
1832 local size off bs
1833
1834 require_zbd || return "$SKIP_TESTCASE"
1835 require_nullb || return "$SKIP_TESTCASE"
1836 require_badblock || return "$SKIP_TESTCASE"
1837
1838 prep_write
1839 off=$((first_sequential_zone_sector * 512))
1840 bs=$(min "$(max $((zone_size / 64)) "$min_seq_write_size")" "$zone_cap_bs")
1841 set_badblocks "$off" "$((bs / 2))" > /dev/null
1842 size=$((4 * zone_size))
1843 run_fio_on_seq "$(ioengine "psync")" --rw=write --offset="$off" \
1844 --size="$size" --bs="$bs" --continue_on_error=1 \
1845 --recover_zbd_write_error=1 --ignore_error=,EIO:61 \
1846 >>"${logfile}.${test_number}" 2>&1 || return $?
1847 grep -qe "Failed to recover write pointer" "${logfile}.${test_number}"
1848}
1849
1850# Multi job sequential async write to sequential zones, with continue_on_error
1851# with failures in the recovery writes.
1852test75() {
1853 local size off bs
1854
1855 require_zbd || return "$SKIP_TESTCASE"
1856 require_nullb || return "$SKIP_TESTCASE"
1857 require_badblock || return "$SKIP_TESTCASE"
1858
1859 prep_write
1860 off=$((first_sequential_zone_sector * 512))
1861 bs=$(min "$(max $((zone_size / 64)) "$min_seq_write_size")" "$zone_cap_bs")
1862 set_badblocks "$off" $((bs / 2)) > /dev/null
1863 size=$((zone_size * 4))
1864 run_fio --name=w --filename="${dev}" --rw=write "$(ioengine "libaio")" \
1865 --iodepth=32 --numjob=8 --group_reporting=1 --offset="$off" \
1866 --size="$size" --bs="$bs" --zonemode=zbd --direct=1 \
1867 --zonesize="$zone_size" --continue_on_error=1 \
1868 --recover_zbd_write_error=1 --debug=zbd \
1869 >>"${logfile}.${test_number}" 2>&1 || return $?
1870 grep -qe "Failed to recover write pointer" "${logfile}.${test_number}"
1871}
1872
beba3d03 1873SECONDS=0
191d1d1a
BVA
1874tests=()
1875dynamic_analyzer=()
1876reset_all_zones=
ccf9d1ef 1877reset_before_write=
6dcb098d
DF
1878use_libzbc=
1879zbd_debug=
7ce7422a 1880max_open_zones_opt=
56e87b2f 1881quit_on_err=
0360d61f 1882force_io_uring=
12067650 1883start_test=1
191d1d1a
BVA
1884
1885while [ "${1#-}" != "$1" ]; do
1886 case "$1" in
1887 -d) dynamic_analyzer=(valgrind "--read-var-info=yes" "--tool=drd"
1888 "--show-confl-seg=no");
1889 shift;;
1890 -e) dynamic_analyzer=(valgrind "--read-var-info=yes" "--tool=helgrind");
1891 shift;;
6dcb098d 1892 -l) use_libzbc=1; shift;;
191d1d1a 1893 -r) reset_all_zones=1; shift;;
ccf9d1ef 1894 -w) reset_before_write=1; shift;;
191d1d1a 1895 -t) tests+=("$2"); shift; shift;;
7ce7422a 1896 -o) max_open_zones_opt="${2}"; shift; shift;;
12067650 1897 -s) start_test=$2; shift; shift;;
191d1d1a
BVA
1898 -v) dynamic_analyzer=(valgrind "--read-var-info=yes");
1899 shift;;
56e87b2f 1900 -q) quit_on_err=1; shift;;
6dcb098d 1901 -z) zbd_debug=1; shift;;
0360d61f 1902 -u) force_io_uring=1; shift;;
191d1d1a 1903 --) shift; break;;
1cae9fe4 1904 *) usage; exit 1;;
191d1d1a
BVA
1905 esac
1906done
1907
1908if [ $# != 1 ]; then
1909 usage
1910 exit 1
1911fi
1912
0360d61f
DF
1913if [ -n "$use_libzbc" -a -n "$force_io_uring" ]; then
1914 echo "Please specify only one of -l and -u options"
1915 exit 1
1916fi
1917
191d1d1a
BVA
1918# shellcheck source=functions
1919source "$(dirname "$0")/functions" || exit $?
1920
7ce7422a
SK
1921global_var_opts=()
1922job_var_opts=()
6dcb098d 1923if [ -n "$zbd_debug" ]; then
7ce7422a 1924 global_var_opts+=("--debug=zbd")
6dcb098d 1925fi
191d1d1a
BVA
1926dev=$1
1927realdev=$(readlink -f "$dev")
1928basename=$(basename "$realdev")
6dcb098d
DF
1929
1930if [[ -b "$realdev" ]]; then
1931 major=$((0x$(stat -L -c '%t' "$realdev"))) || exit $?
1932 minor=$((0x$(stat -L -c '%T' "$realdev"))) || exit $?
1933 disk_size=$(($(<"/sys/dev/block/$major:$minor/size")*512))
1934
1935 # When the target is a partition device, get basename of its
1936 # holder device to access sysfs path of the holder device
1937 if [[ -r "/sys/dev/block/$major:$minor/partition" ]]; then
1938 realsysfs=$(readlink "/sys/dev/block/$major:$minor")
1939 basename=$(basename "${realsysfs%/*}")
1940 fi
557cfc51 1941 min_seq_write_size=$(min_seq_write_size "$basename")
6dcb098d
DF
1942 case "$(<"/sys/class/block/$basename/queue/zoned")" in
1943 host-managed|host-aware)
1944 is_zbd=true
552e214c
SK
1945 if ! check_blkzone "${dev}"; then
1946 exit 1
1947 fi
6dcb098d
DF
1948 if ! result=($(first_sequential_zone "$dev")); then
1949 echo "Failed to determine first sequential zone"
1950 exit 1
1951 fi
1952 first_sequential_zone_sector=${result[0]}
1953 sectors_per_zone=${result[1]}
1954 zone_size=$((sectors_per_zone * 512))
7d5a66e1 1955 unrestricted_reads=$(urswrz "$dev")
6dcb098d
DF
1956 if ! max_open_zones=$(max_open_zones "$dev"); then
1957 echo "Failed to determine maximum number of open zones"
1958 exit 1
1959 fi
1a5411cd 1960 max_active_zones=$(max_active_zones "$dev")
6dcb098d
DF
1961 set_io_scheduler "$basename" deadline || exit $?
1962 if [ -n "$reset_all_zones" ]; then
1963 reset_zone "$dev" -1
1964 fi
1965 ;;
1966 *)
1967 first_sequential_zone_sector=$(((disk_size / 2) &
79201772
SK
1968 (min_seq_write_size - 1)))
1969 zone_size=$(max 65536 "$min_seq_write_size")
6dcb098d
DF
1970 sectors_per_zone=$((zone_size / 512))
1971 max_open_zones=128
1a5411cd 1972 max_active_zones=0
7d5a66e1 1973 unrestricted_reads=1
6dcb098d
DF
1974 set_io_scheduler "$basename" none || exit $?
1975 ;;
1976 esac
12067650 1977
6dcb098d
DF
1978elif [[ -c "$realdev" ]]; then
1979 # For an SG node, we must have libzbc option specified
1980 if [[ ! -n "$use_libzbc" ]]; then
1981 echo "Character device files can only be used with -l (libzbc) option"
1982 exit 1
1983 fi
1984
1985 if ! $(is_zbc "$dev"); then
1986 echo "Device is not a ZBC disk"
1987 exit 1
1988 fi
191d1d1a 1989 is_zbd=true
6dcb098d
DF
1990
1991 if ! disk_size=($(( $(zbc_disk_sectors "$dev") * 512))); then
1992 echo "Failed to determine disk size"
1993 exit 1
1994 fi
557cfc51
SK
1995 if ! min_seq_write_size=($(zbc_physical_block_size "$dev")); then
1996 echo "Failed to determine physical block size"
6dcb098d
DF
1997 exit 1
1998 fi
191d1d1a 1999 if ! result=($(first_sequential_zone "$dev")); then
6dcb098d
DF
2000 echo "Failed to determine first sequential zone"
2001 exit 1
191d1d1a
BVA
2002 fi
2003 first_sequential_zone_sector=${result[0]}
2004 sectors_per_zone=${result[1]}
2005 zone_size=$((sectors_per_zone * 512))
7d5a66e1 2006 unrestricted_reads=$(urswrz "$dev")
191d1d1a 2007 if ! max_open_zones=$(max_open_zones "$dev"); then
6dcb098d
DF
2008 echo "Failed to determine maximum number of open zones"
2009 exit 1
191d1d1a 2010 fi
1a5411cd 2011 max_active_zones=0
191d1d1a 2012 if [ -n "$reset_all_zones" ]; then
6dcb098d 2013 reset_zone "$dev" -1
191d1d1a 2014 fi
6dcb098d
DF
2015fi
2016
7ce7422a
SK
2017if [[ -n ${max_open_zones_opt} ]]; then
2018 # Override max_open_zones with the script option value
2019 max_open_zones="${max_open_zones_opt}"
351fe910 2020 global_var_opts+=("--ignore_zone_limits=1")
7ce7422a
SK
2021 job_var_opts+=("--max_open_zones=${max_open_zones_opt}")
2022fi
2023
6dcb098d
DF
2024echo -n "First sequential zone starts at sector $first_sequential_zone_sector;"
2025echo " zone size: $((zone_size >> 20)) MB"
191d1d1a 2026
1ae82d67
SK
2027zone_cap_bs=$(zone_cap_bs "$dev" "$zone_size")
2028
191d1d1a 2029if [ "${#tests[@]}" = 0 ]; then
106a71cd
SK
2030 readarray -t tests < <(declare -F | grep "test[0-9]*" | \
2031 tr -c -d "[:digit:]\n" | sort -n)
191d1d1a
BVA
2032fi
2033
2034logfile=$0.log
2035
72176dc7 2036passed=0
d480b019 2037skipped=0
72176dc7 2038failed=0
332fa178
DF
2039if [ -t 1 ]; then
2040 red="\e[1;31m"
2041 green="\e[1;32m"
d480b019 2042 cyan="\e[1;36m"
332fa178
DF
2043 end="\e[m"
2044else
2045 red=""
2046 green=""
2047 end=""
2048fi
191d1d1a 2049rc=0
332fa178 2050
c96b385b
DF
2051intr=0
2052trap 'intr=1' SIGINT
d480b019 2053ret=0
c96b385b 2054
191d1d1a 2055for test_number in "${tests[@]}"; do
12067650 2056 [ "${test_number}" -lt "${start_test}" ] && continue
191d1d1a 2057 rm -f "${logfile}.${test_number}"
d480b019 2058 unset SKIP_REASON
332fa178 2059 echo -n "Running test $(printf "%02d" $test_number) ... "
d480b019
SK
2060 eval "test$test_number"
2061 ret=$?
2062 if ((!ret)) && check_log $test_number; then
191d1d1a 2063 status="PASS"
332fa178 2064 cc_status="${green}${status}${end}"
72176dc7 2065 ((passed++))
d480b019
SK
2066 elif ((ret==SKIP_TESTCASE)); then
2067 status="SKIP"
2068 echo "${SKIP_REASON}" >> "${logfile}.${test_number}"
2069 cc_status="${cyan}${status}${end} ${SKIP_REASON}"
2070 ((skipped++))
191d1d1a
BVA
2071 else
2072 status="FAIL"
332fa178 2073 cc_status="${red}${status}${end}"
72176dc7 2074 ((failed++))
191d1d1a
BVA
2075 rc=1
2076 fi
332fa178 2077 echo -e "$cc_status"
191d1d1a 2078 echo "$status" >> "${logfile}.${test_number}"
c96b385b 2079 [ $intr -ne 0 ] && exit 1
56e87b2f 2080 [ -n "$quit_on_err" -a "$rc" -ne 0 ] && exit 1
191d1d1a
BVA
2081done
2082
72176dc7 2083echo "$passed tests passed"
d480b019
SK
2084if [ $skipped -gt 0 ]; then
2085 echo " $skipped tests skipped"
2086fi
72176dc7 2087if [ $failed -gt 0 ]; then
d480b019 2088 echo " $failed tests failed"
72176dc7 2089fi
beba3d03 2090echo "Run time: $(TZ=UTC0 printf "%(%H:%M:%S)T\n" $(( SECONDS )) )"
191d1d1a 2091exit $rc