restore-volumes: fail loudly when static offload cannot fit on /slowdisk

A silent fallback to primary-disk extraction violates the caller's NVMe
capacity math now that the planner treats slowdisk as a separate pool.
When SLOWDISK=True and the manifest's static sizes (accurate, replacing
the whole-archive x2 estimate that false-refuses large restores) do not
fit above the floor, error out with the explicit remedy: re-run with
--no-slowdisk as the conscious override. Operator directive 2026-07-09.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
rob
2026-07-09 07:20:52 +00:00
parent 331a9c27a8
commit a0b47b3631

View File

@@ -108,8 +108,24 @@ prep_static_offload() {
esac
[ -d /slowdisk ] || { echo " /slowdisk absent — no static offload"; return 0; }
[ -f "$meta" ] || { echo " no manifest ($meta) — no static offload"; return 0; }
if ! slowdisk_floor_allows_offload "$newest_file"; then
return 0
# Fit check against the manifest's actual static sizes (not the old whole-archive x2
# estimate, which false-refuses restores whose statics are a fraction of the archive).
# When the statics do NOT fit, FAIL LOUDLY instead of silently extracting everything
# onto the primary disk: a silent NVMe fallback violates the caller's capacity math
# (operator directive 2026-07-09). --no-slowdisk is the conscious override.
local need_gb free_gb floor_gb
floor_gb="${SLOWDISK_FLOOR_GB:-150}"
free_gb=$(slowdisk_free_gb || echo "")
need_gb=$(awk 'NR>3 && NF>=2 {
s=$1; mult=1
if (s ~ /TB$/) mult=1024; else if (s ~ /MB$/) mult=1/1024; else if (s ~ /KB$/) mult=1/1048576
gsub(/[A-Za-z]/, "", s); total+=s*mult
} END {printf "%d", total*1.05 + 1}' "$meta")
if [[ "$free_gb" =~ ^[0-9]+$ && "$need_gb" =~ ^[0-9]+$ ]] && (( free_gb - need_gb < floor_gb )); then
echo "ERROR: static offload does not fit on /slowdisk (need ~${need_gb}G static files, free ${free_gb}G, floor ${floor_gb}G)." >&2
echo " This restore can only fit with --no-slowdisk (extracts everything onto the" >&2
echo " primary disk — NVMe capacity accounting will differ from the offload plan)." >&2
exit 1
fi
static_offload_used=1
# manifest data lines (after the 3-line header) are "<size> <relpath>"