Split per O&M lane work order. Full history: KNEL/PFVCluster. https://projects.knownelement.com/issues/769#note-4152
87 lines
4.0 KiB
Bash
87 lines
4.0 KiB
Bash
#!/bin/bash
|
|
# bench-run.sh — standardized fleet benchmark (fio + iperf3). [#709]
|
|
# Same tool, same shape, everywhere: Proxmox LXCs, guests, containers.
|
|
# Non-destructive: fio writes only its own files under BENCH_DIR.
|
|
#
|
|
# Usage:
|
|
# BENCH_DIR=/path bench-run.sh # storage bench on /path (default /var/tmp)
|
|
# IPERF_SERVER=host bench-run.sh # + network test to that iperf3 server
|
|
# bench-run.sh --server # run as iperf3 server (one shot)
|
|
# Output: one "BENCH|key|value" line per metric (grep-friendly), plus meta.
|
|
set -u
|
|
|
|
RUNTIME="${BENCH_RUNTIME:-20}"
|
|
SIZE="${BENCH_SIZE:-1G}"
|
|
BENCH_DIR="${BENCH_DIR:-/var/tmp}"
|
|
STAMP="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
HOSTID="$(hostname -s)"
|
|
|
|
b() { printf 'BENCH|%s|%s|%s\n' "$HOSTID" "$1" "$2"; }
|
|
|
|
if [ "${1:-}" = "--server" ]; then
|
|
exec iperf3 -s -1
|
|
fi
|
|
|
|
command -v fio >/dev/null 2>&1 || { echo "ERROR: fio not installed (see install-bench.sh)" >&2; exit 1; }
|
|
|
|
mkdir -p "$BENCH_DIR"
|
|
b meta stamp "$STAMP"
|
|
b meta path "$BENCH_DIR"
|
|
b meta runtime "$RUNTIME"
|
|
b meta size "$SIZE"
|
|
|
|
# context: load, PSI latency (pressure stall info — the latencytop
|
|
# replacement on modern kernels), and the backing device of BENCH_DIR
|
|
b meta load "$(cat /proc/loadavg)"
|
|
if [ -d /proc/pressure ]; then
|
|
for rsc in io cpu memory; do
|
|
[ -r "/proc/pressure/$rsc" ] && \
|
|
b "psi_${rsc}_some_avg10" "$(awk '{for(i=1;i<=NF;i++) if($i ~ /^avg10=/) sub("avg10=","",$i)} /^some/ {print $2; exit}' "/proc/pressure/$rsc" 2>/dev/null)"
|
|
done
|
|
fi
|
|
DEV=$(df -P "$BENCH_DIR" | awk 'NR==2 {print $1}')
|
|
b meta bench_device "$DEV"
|
|
[ -r "/sys/block/$(basename "$DEV")/queue/rotational" ] && \
|
|
b meta bench_device_rotational "$(cat "/sys/block/$(basename "$DEV")/queue/rotational")"
|
|
|
|
# fio may print human notes (e.g. sync-engine warnings) before the JSON on
|
|
# stdout; strip everything before the opening brace so jq always gets JSON.
|
|
parse_fio() { # $1=json-file $2=testname $3=read|write
|
|
sed -n '/^{/,$p' "$1" | jq -r --arg n "$2" --arg d "$3" '
|
|
.jobs[0] as $j |
|
|
($n) + "|iops=" + ($j[$d].iops | tostring) + "|" +
|
|
"bw_kbps=" + ($j[$d].bw | tostring) + "|" +
|
|
"p99_ms=" + (($j[$d].clat_ns.percentile["99.000000"] // 0) / 1000000 | tostring)' | while IFS='|' read -r n rest; do
|
|
printf 'BENCH|%s|%s|%s\n' "$HOSTID" "$n" "$rest"
|
|
done
|
|
}
|
|
|
|
run_fio() { # $1=testname $2=read|write $3+=fio-args
|
|
local name="$1"; local dir="$2"; shift 2
|
|
fio --name="$name" --output-format=json --timeout=120 "$@" \
|
|
> "$BENCH_DIR/.fio-out.json" 2>"$BENCH_DIR/.fio-err" || {
|
|
b "fio_${name}" ERROR; return; }
|
|
parse_fio "$BENCH_DIR/.fio-out.json" "$name" "$dir"
|
|
}
|
|
|
|
# 4k random read/write (IOPS), 1M sequential read/write (MB/s); direct to skip cache
|
|
run_fio randread4k read --filename="$BENCH_DIR/perf-test-file" --rw=randread --bs=4k --direct=1 --iodepth=16 --time_based --runtime="$RUNTIME" --size="$SIZE"
|
|
run_fio randwrite4k write --filename="$BENCH_DIR/perf-test-file" --rw=randwrite --bs=4k --direct=1 --iodepth=16 --time_based --runtime="$RUNTIME" --size="$SIZE"
|
|
run_fio seqread1m read --filename="$BENCH_DIR/perf-test-file" --rw=read --bs=1M --direct=1 --iodepth=8 --time_based --runtime="$RUNTIME" --size="$SIZE"
|
|
run_fio seqwrite1m write --filename="$BENCH_DIR/perf-test-file" --rw=write --bs=1M --direct=1 --iodepth=8 --time_based --runtime="$RUNTIME" --size="$SIZE"
|
|
|
|
rm -f "$BENCH_DIR/.fio-out.json" "$BENCH_DIR/.fio-err"
|
|
|
|
# post-run pressure + load (did the bench itself saturate the box?)
|
|
b meta load_end "$(cat /proc/loadavg)"
|
|
[ -r /proc/pressure/io ] && \
|
|
b psi_io_some_avg10_end "$(awk '/^some/ {for(i=1;i<=NF;i++) if($i ~ /^avg10=/) {sub("avg10=","",$i); print $i; exit}}' /proc/pressure/io)"
|
|
|
|
# network: only when a server is provided
|
|
if [ -n "${IPERF_SERVER:-}" ] && command -v iperf3 >/dev/null 2>&1; then
|
|
NET=$(iperf3 -c "$IPERF_SERVER" -t 10 -P 4 -J 2>/dev/null | jq -r '.end.sum_received.bits_per_second' 2>/dev/null)
|
|
[ -n "$NET" ] && b iperf3_rx_bps "$NET"
|
|
fi
|
|
|
|
b meta end "$STAMP"
|