| 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 | } |