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