#!/usr/bin/env bash # Refresh the SD card (mmcblk0p2) as a live boot-fallback clone of the # running root filesystem. Run manually after a push: # sudo ./failover/sync-sd-backup.sh # # EEPROM BOOT_ORDER falls back to the SD card if the primary boot disk # (NVMe) doesn't come up. /etc/fstab, /etc/machine-id, and /var/log are # excluded from the sync so the clone keeps its own partition identity # (PARTUUIDs differ per disk) and boot/journal history instead of # inheriting the source disk's — see failover/README or repo memory # "sd-fallback-fstab-clobber" for what breaks if those leak across. set -euo pipefail [ "$(id -u)" -eq 0 ] || { echo "Run as root (sudo)." >&2; exit 1; } SD_ROOT_PART=/dev/mmcblk0p2 MOUNT_POINT=/mnt/sd-backup-root root_src=$(findmnt -no SOURCE /) if [ "$root_src" = "$SD_ROOT_PART" ]; then echo "Currently booted from $SD_ROOT_PART — refusing to sync SD onto itself." >&2 exit 1 fi mkdir -p "$MOUNT_POINT" mounted_here=0 if ! mountpoint -q "$MOUNT_POINT"; then mount "$SD_ROOT_PART" "$MOUNT_POINT" mounted_here=1 else mount -o remount,rw "$MOUNT_POINT" fi cleanup() { if [ "$mounted_here" -eq 1 ]; then umount "$MOUNT_POINT" fi } trap cleanup EXIT # rsync exit 24 ("partial transfer due to vanished source files") is expected on a # live root — files like container shm sockets or in-progress logs routinely disappear # mid-sync. Tolerate that one code; anything else is a real failure and still aborts. rc=0 rsync -aHAX --numeric-ids --delete \ --info=progress2 \ --exclude=/proc/* --exclude=/sys/* --exclude=/dev/* --exclude=/run/* \ --exclude=/tmp/* --exclude=/mnt/* --exclude=/media/* --exclude=/lost+found \ --exclude=/boot/firmware/* --exclude=/swapfile \ --exclude=/etc/fstab --exclude=/etc/machine-id --exclude=/var/log/* \ --stats / "$MOUNT_POINT/" || rc=$? if [ "$rc" -ne 0 ] && [ "$rc" -ne 24 ]; then echo "rsync failed (exit $rc)." >&2 exit "$rc" fi if [ "$rc" -eq 24 ]; then echo "Note: some files vanished mid-sync (rsync exit 24) — normal on a live root." >&2 fi echo "SD backup ($SD_ROOT_PART) synced from $root_src."