diff --git a/proxmox/perf/bench/Dockerfile b/proxmox/perf/bench/Dockerfile index 1f14244..23c37e3 100644 --- a/proxmox/perf/bench/Dockerfile +++ b/proxmox/perf/bench/Dockerfile @@ -3,7 +3,7 @@ FROM debian:12-slim RUN apt-get update -qq && apt-get install -y -qq --no-install-recommends \ - fio iperf3 jq ca-certificates \ + fio iperf3 jq libaio1 ca-certificates \ && rm -rf /var/lib/apt/lists/* COPY bench-run.sh /usr/local/bin/bench-run.sh diff --git a/proxmox/perf/bench/bench-run.sh b/proxmox/perf/bench/bench-run.sh index 185f8fb..b00b7e3 100644 --- a/proxmox/perf/bench/bench-run.sh +++ b/proxmox/perf/bench/bench-run.sh @@ -30,33 +30,31 @@ b meta path "$BENCH_DIR" b meta runtime "$RUNTIME" b meta size "$SIZE" -run_fio() { # $1=testname $2=fio-args... - local name="$1"; shift +# 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; } - if command -v jq >/dev/null 2>&1; then - while IFS='|' read -r n rest; do - printf 'BENCH|%s|%s|%s\n' "$HOSTID" "$n" "$rest" - done < <(jq -r --arg n "$name" ' - .jobs[0] as $j | - ($n) + "|iops=" + ($j.read.iops // $j.write.iops | tostring) + "|" + - "bw_kbps=" + (($j.read.bw // $j.write.bw) | tostring) + "|" + - "p99_ms=" + (($j.read.clat_ns.percentile["99.000000"] // $j.write.clat_ns.percentile["99.000000"] // 0) / 1000000 | tostring)' \ - "$BENCH_DIR/.fio-out.json") - else - # no jq: minimal grep fallback - grep -oE '"(iops|bw)":[0-9.]+' "$BENCH_DIR/.fio-out.json" | head -2 | while IFS=: read -r k v; do - b "fio_${name}_${k}" "$v" - done - fi + 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 --filename="$BENCH_DIR/perf-test-file" --rw=randread --bs=4k --direct=1 --iodepth=16 --time_based --runtime="$RUNTIME" --size="$SIZE" -run_fio randwrite4k --filename="$BENCH_DIR/perf-test-file" --rw=randwrite --bs=4k --direct=1 --iodepth=16 --time_based --runtime="$RUNTIME" --size="$SIZE" -run_fio seqread1m --filename="$BENCH_DIR/perf-test-file" --rw=read --bs=1M --direct=1 --iodepth=8 --time_based --runtime="$RUNTIME" --size="$SIZE" -run_fio seqwrite1m --filename="$BENCH_DIR/perf-test-file" --rw=write --bs=1M --direct=1 --iodepth=8 --time_based --runtime="$RUNTIME" --size="$SIZE" +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" diff --git a/proxmox/perf/bench/install-bench.sh b/proxmox/perf/bench/install-bench.sh index c6899fe..957014b 100644 --- a/proxmox/perf/bench/install-bench.sh +++ b/proxmox/perf/bench/install-bench.sh @@ -5,5 +5,5 @@ set -eu export DEBIAN_FRONTEND=noninteractive apt-get update -qq -apt-get install -y -qq fio iperf3 jq >/dev/null +apt-get install -y -qq fio iperf3 jq libaio1 >/dev/null echo "bench toolset installed: fio=$(fio --version 2>/dev/null | awk '{print $3}') iperf3=$(iperf3 --version 2>/dev/null | awk 'NR==1{print $2}')" diff --git a/proxmox/perf/bench/lxc-bench-setup.sh b/proxmox/perf/bench/lxc-bench-setup.sh index 12242a5..38683eb 100644 --- a/proxmox/perf/bench/lxc-bench-setup.sh +++ b/proxmox/perf/bench/lxc-bench-setup.sh @@ -33,8 +33,10 @@ trap cleanup EXIT TPL=$(pveam list local 2>/dev/null | grep -oE 'local:vztmpl/[a-z0-9-]*debian-12-standard[^ ]*\.tar\.zst' | head -1 || true) if [ -z "$TPL" ]; then pveam update >/dev/null - pveam download local debian-12-standard_12.7-1_amd64.tar.zst >/dev/null - TPL=$(pveam list local | grep -oE 'local:vztmpl/[a-z0-9-]*debian-12-standard[^ ]*\.tar\.zst' | head -1) + DL=$(pveam available --section system 2>/dev/null | grep -oE 'debian-12-standard[^ ]*\.tar\.zst' | sort -V | tail -1) + [ -n "$DL" ] || { echo "[bench-lxc] ERROR: no debian-12 LXC template in pveam" >&2; exit 1; } + pveam download local "$DL" >/dev/null + TPL=$(pveam list local | grep -oE "local:vztmpl/$DL" | head -1) fi echo "[bench-lxc] template: $TPL" @@ -50,7 +52,7 @@ pct start "$CTID" sleep 5 # toolset in (same installer the guests use; piped in, nothing fetched from outside) -pct exec "$CTID" -- bash -c "export DEBIAN_FRONTEND=noninteractive; apt-get update -qq >/dev/null; apt-get install -y -qq fio iperf3 jq >/dev/null" +pct exec "$CTID" -- bash -c "export DEBIAN_FRONTEND=noninteractive; apt-get update -qq >/dev/null; apt-get install -y -qq fio iperf3 jq libaio1 >/dev/null" BDIR="/mnt/bench" [ -z "$STORE" ] && BDIR="/var/tmp"