static-file size/manifest: match offloaded (symlinked) dirs + show offload indicator

find -type d skipped static dirs that are already offloaded (a symlink to /slowdisk is type
l, not d) — so show-static-file-size.sh reported zero static for an offloaded node (e.g. bob
on de-35), and backup-node.sh would drop them from the manifest (breaking re-offload on the
next restore). Match dirs AND symlinks now (root-level entries too).

show-static-file-size.sh also tags each static dir with its location:
[OFFLOADED -> /slowdisk/...], [on-disk], or [BROKEN SYMLINK ...].

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-15 05:03:16 +00:00
parent 57b5757a85
commit baf26b234f
2 changed files with 24 additions and 9 deletions

View File

@@ -42,11 +42,14 @@ generate_volume_metadata() {
# slash is a path-suffix, so any prefix matches (network-prefixed nitro freezers,
# nested l2geth geth/geth/...). Record the CONCRETE relative path so restore-volumes
# can recreate the exact static-file -> /slowdisk symlink.
# Match real dirs AND symlinks: an already-OFFLOADED static dir is a symlink to
# /slowdisk, which find -type d alone would skip (then it would be dropped from the
# manifest and the next restore would not re-offload it).
local matches=() m rel
if [[ "$path" == */* ]]; then
while IFS= read -r m; do matches+=("$m"); done < <(find "$prefix/_data" -type d -path "*/$path" 2>/dev/null)
while IFS= read -r m; do matches+=("$m"); done < <(find "$prefix/_data" \( -type d -o -type l \) -path "*/$path" 2>/dev/null)
else
[[ -d "$prefix/_data/$path" ]] && matches+=("$prefix/_data/$path")
m="$prefix/_data/$path"; { [ -d "$m" ] || [ -L "$m" ]; } && matches+=("$m")
fi
for m in "${matches[@]}"; do
rel="${m#"$prefix/_data/"}"

View File

@@ -26,21 +26,33 @@ for key in $keys; do
# Skip empty lines
[[ -z "$path" ]] && continue
# Match rule: an entry with NO slash is root-level only (depth-1 under _data),
# so e.g. `snapshots` won't catch postgres pg_logical/snapshots. An entry WITH a
# slash is a path-suffix, so any prefix matches (network-prefixed nitro freezers
# like arbitrum-one/nitro/l2chaindata/ancient, nested l2geth geth/geth/...).
# Match rule: an entry with NO slash is root-level only (depth-1 under _data), so
# e.g. `snapshots` won't catch postgres pg_logical/snapshots. An entry WITH a slash
# is a path-suffix (any prefix: network-prefixed nitro, nested l2geth geth/geth/...).
# Match real dirs AND symlinks: an OFFLOADED static dir is a symlink to /slowdisk,
# which `find -type d` alone would skip.
matches=()
if [[ "$path" == */* ]]; then
while IFS= read -r d; do matches+=("$d"); done < <(find "$prefix/_data" -type d -path "*/$path" 2>/dev/null)
while IFS= read -r d; do matches+=("$d"); done < <(find "$prefix/_data" \( -type d -o -type l \) -path "*/$path" 2>/dev/null)
else
[[ -d "$prefix/_data/$path" ]] && matches+=("$prefix/_data/$path")
m="$prefix/_data/$path"; { [ -d "$m" ] || [ -L "$m" ]; } && matches+=("$m")
fi
for m in "${matches[@]}"; do
size=$(du -sL "$m" 2>/dev/null | awk '{print $1}')
static_size=$((static_size + ${size:-0}))
size_formatted=$(echo "$(( ${size:-0} * 1024 ))" | numfmt --to=iec --suffix=B --format="%.2f")
echo "$size_formatted $m" >&2
# offload indicator: is this static dir symlinked out to the /slowdisk extra disk?
if [ -L "$m" ]; then
tgt=$(readlink -f "$m" 2>/dev/null)
case "$tgt" in
/slowdisk/*) loc="[OFFLOADED -> $tgt]" ;;
"") loc="[BROKEN SYMLINK -> $(readlink "$m" 2>/dev/null)]" ;;
*) loc="[SYMLINK -> $tgt]" ;;
esac
else
loc="[on-disk]"
fi
echo "$size_formatted $m $loc" >&2
done
done < "$static_file_list"
fi