slowdisk offload: fix EXDEV - extract statics via tar --transform, not through symlinks

tar cannot create files through a directory symlink whose target is on
another device: open() fails with 'Invalid cross-device link' even under
--keep-directory-symlink (reproduced, GNU tar 1.34 and 1.35). This killed
the katana->uk-4 provision (place-provision-katana-EU-NorthWest-p1) and
means the slowdisk EXTRACT path never worked on hosts with a separate
/slowdisk device. Rewrite member paths with --transform so tar writes
directly into /slowdisk/rpc_<key>__data_<rel>; the symlink stays for the
container's runtime view. Also aligns restore-volumes' nested-path target
naming to the double-underscore convention clone-backup already uses.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
rob
2026-07-11 01:50:08 +00:00
parent defb9133ea
commit fccf279262
2 changed files with 20 additions and 6 deletions

View File

@@ -224,6 +224,7 @@ setup_slowdisk_structure() {
return 1
fi
SLOWDISK_TRANSFORMS=""
echo "Setting up SLOWDISK structure for $key"
echo " Static size: $((static_size_kb / 1024))MB"
echo " Static paths: ${#static_paths[@]}"
@@ -253,6 +254,11 @@ setup_slowdisk_structure() {
local slowdisk_path="${slowdisk_base}/rpc_${key}__data_${path//\//__}"
local target_path="${volume_path}/${path}"
local target_dir=$(dirname "$target_path")
# tar cannot extract THROUGH a symlink to another device (EXDEV
# "Invalid cross-device link", reproduced GNU tar 1.34+1.35 2026-07-11 -
# killed the katana->uk-4 provision). Collect --transform rewrites so tar
# writes directly into /slowdisk; the symlink remains for runtime.
SLOWDISK_TRANSFORMS+=" --transform='s|^\\(\\./\\)\\?var/lib/docker/volumes/rpc_${key}/_data/${path}|slowdisk/rpc_${key}__data_${path//\//__}|'"
# Create parent directories in volume
$SSH_CMD "$DEST_HOST" "mkdir -p '$target_dir'"
@@ -327,7 +333,7 @@ transfer_backup() {
# Use --skip-old-files to avoid overwriting existing symlinks/directories
# and --keep-directory-symlink so tar extracts THROUGH the pre-created dir symlinks
# instead of trying to mkdir over them (which fails with 'Cannot mkdir: File exists')
tar_extract_opts="-xf - -C / --skip-old-files --keep-directory-symlink"
tar_extract_opts="-xf - -C / --skip-old-files --keep-directory-symlink${SLOWDISK_TRANSFORMS}"
echo "SLOWDISK structure ready, will extract respecting symlinks"
else
echo "Warning: Failed to setup SLOWDISK structure, falling back to normal extraction"
@@ -513,7 +519,7 @@ transfer_backup_ssh() {
if setup_slowdisk_structure "$key" "$static_size_kb" "${static_paths[@]}"; then
# and --keep-directory-symlink so tar extracts THROUGH the pre-created dir symlinks
# instead of trying to mkdir over them (which fails with 'Cannot mkdir: File exists')
tar_extract_opts="-xf - -C / --skip-old-files --keep-directory-symlink"
tar_extract_opts="-xf - -C / --skip-old-files --keep-directory-symlink${SLOWDISK_TRANSFORMS}"
echo "SLOWDISK structure ready, will extract respecting symlinks"
else
echo "Warning: Failed to setup SLOWDISK structure, falling back to normal extraction"