Merge branch 'master' of https://github.com/bvanassche/fio
[fio.git] / t / zbd / functions
1 #!/bin/bash
2
3 blkzone=$(type -p blkzone 2>/dev/null)
4 sg_inq=$(type -p sg_inq 2>/dev/null)
5 zbc_report_zones=$(type -p zbc_report_zones 2>/dev/null)
6 zbc_reset_zone=$(type -p zbc_reset_zone 2>/dev/null)
7 if [ -z "${blkzone}" ] &&
8        { [ -z "${zbc_report_zones}" ] || [ -z "${zbc_reset_zone}" ]; }; then
9     echo "Error: neither blkzone nor zbc_report_zones is available"
10     exit 1
11 fi
12
13 # Reports the starting sector and length of the first sequential zone of device
14 # $1.
15 first_sequential_zone() {
16     local dev=$1
17
18     if [ -n "${blkzone}" ]; then
19         ${blkzone} report "$dev" |
20             sed -n 's/^[[:blank:]]*start:[[:blank:]]\([0-9a-zA-Z]*\),[[:blank:]]len[[:blank:]]\([0-9a-zA-Z]*\),.*type:[[:blank:]]2(.*/\1 \2/p' |
21             {
22                 read -r starting_sector length &&
23                     # Convert from hex to decimal
24                     echo $((starting_sector)) $((length))
25             }
26     else
27         ${zbc_report_zones} "$dev" |
28             sed -n 's/^Zone [0-9]*: type 0x2 .*, sector \([0-9]*\), \([0-9]*\) sectors,.*$/\1 \2/p' |
29             head -n1
30     fi
31 }
32
33 max_open_zones() {
34     local dev=$1
35
36     if [ -n "${sg_inq}" ]; then
37         if ! ${sg_inq} -e --page=0xB6 --len=20 --hex "$dev" 2> /dev/null; then
38             # Non scsi device such as null_blk can not return max open zones.
39             # Use default value.
40             echo 128
41         else
42             ${sg_inq} -e --page=0xB6 --len=20 --hex "$dev" | tail -1 |
43                 {
44                     read -r offset b0 b1 b2 b3 trailer || return $?
45                     # Convert from hex to decimal
46                     max_nr_open_zones=$((0x${b0}))
47                     max_nr_open_zones=$((max_nr_open_zones * 256 + 0x${b1}))
48                     max_nr_open_zones=$((max_nr_open_zones * 256 + 0x${b2}))
49                     max_nr_open_zones=$((max_nr_open_zones * 256 + 0x${b3}))
50                     echo ${max_nr_open_zones}
51                 }
52         fi
53     else
54         ${zbc_report_zones} "$dev" |
55             sed -n 's/^[[:blank:]]*Maximum number of open sequential write required zones:[[:blank:]]*//p'
56     fi
57 }
58
59 # Reset the write pointer of one zone on device $1 at offset $2. The offset
60 # must be specified in units of 512 byte sectors. Offset -1 means reset all
61 # zones.
62 reset_zone() {
63     local dev=$1 offset=$2 sectors
64
65     if [ -n "${blkzone}" ]; then
66         if [ "$offset" -lt 0 ]; then
67             sectors=$(<"/sys/class/block/${dev#/dev/}/size")
68             ${blkzone} reset -o "${offset}" -l "$sectors" "$dev"
69         else
70             ${blkzone} reset -o "${offset}" -c 1 "$dev"
71         fi
72     else
73         if [ "$offset" -lt 0 ]; then
74             ${zbc_reset_zone} -all "$dev" "${offset}" >/dev/null
75         else
76             ${zbc_reset_zone} -sector "$dev" "${offset}" >/dev/null
77         fi
78     fi
79 }
80
81 # Extract the number of bytes that have been transferred from a line like
82 # READ: bw=6847KiB/s (7011kB/s), 6847KiB/s-6847KiB/s (7011kB/s-7011kB/s), io=257MiB (269MB), run=38406-38406msec
83 fio_io() {
84     sed -n 's/^[[:blank:]]*'"$1"'.*, io=\([^[:blank:]]*\).*/\1/p' |
85         tail -n 1 |
86         (
87             read -r io;
88             # Parse <number>.<number><suffix> into n1, n2 and s. See also
89             # num2str().
90             shopt -s extglob
91             n1=${io%${io##*([0-9])}}
92             s=${io#${io%%*([a-zA-Z])}}
93             n2=${io#${n1}}
94             n2=${n2#.}
95             n2=${n2%$s}000
96             n2=${n2:0:3}
97             case "$s" in
98                 KiB) m=10;;
99                 MiB) m=20;;
100                 GiB) m=30;;
101                 B)   m=0;;
102                 *)   return 1;;
103             esac
104             [ -n "$n1" ] || return 1
105             echo $(((n1 << m) + (n2 << m) / 1000))
106         )
107 }
108
109 fio_read() {
110     fio_io 'READ:'
111 }
112
113 fio_written() {
114     fio_io 'WRITE:'
115 }
116
117 fio_reset_count() {
118     local count
119
120     count=$(sed -n 's/^.*write:[^;]*; \([0-9]*\) zone resets$/\1/p')
121     echo "${count:-0}"
122 }