Adapt sync-sd-backup.sh to eMMC-primary R5C layout
The eMMC is now the boot/root device and the SD card is a manual failsafe. U-Boot has no persistent env and always prefers an SD with a boot.scr, so the SD's boot script is kept dormant as boot-failesafe-rename-to:boot.scr. - Locate the SD by root UUID instead of /dev/mmcblk0p2 - Preserve the SD's dormant boot script; never create a live boot.scr and refresh the dormant copy from the eMMC - Copy fstab and armbianEnv.txt with the root UUID rewritten to the SD's - Add rsync -x; drop the Pi-specific /boot/firmware exclude Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+43
-13
@@ -1,26 +1,39 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Refresh the SD card (mmcblk0p2) as a live boot-fallback clone of the
|
# Refresh the SD card as a manual boot-fallback clone of the running root
|
||||||
# running root filesystem. Run manually after a push:
|
# filesystem. Run manually after a push:
|
||||||
# sudo ./failover/sync-sd-backup.sh
|
# sudo ./failover/sync-sd-backup.sh
|
||||||
#
|
#
|
||||||
# EEPROM BOOT_ORDER falls back to the SD card if the primary boot disk
|
# R5C layout: the primary root is the eMMC (mmcblk1p1) and the SD card
|
||||||
# (NVMe) doesn't come up. /etc/fstab, /etc/machine-id, and /var/log are
|
# (root UUID below) is the backup. U-Boot has no persistent env and always
|
||||||
# excluded from the sync so the clone keeps its own partition identity
|
# prefers the SD if it finds a boot.scr there, so the SD's boot.scr is kept
|
||||||
# (PARTUUIDs differ per disk) and boot/journal history instead of
|
# renamed to /boot/boot-failesafe-rename-to:boot.scr. U-Boot then skips the
|
||||||
# inheriting the source disk's — see failover/README or repo memory
|
# SD and boots the eMMC. To boot the SD: rename it back to boot.scr (e.g.
|
||||||
# "sd-fallback-fstab-clobber" for what breaks if those leak across.
|
# from another machine with the SD mounted, or from a U-Boot console).
|
||||||
|
#
|
||||||
|
# Not copied verbatim, so the clone keeps its own identity:
|
||||||
|
# /etc/fstab, /boot/armbianEnv.txt copied with the root UUID rewritten
|
||||||
|
# /boot/boot.scr never created; the eMMC's copy is
|
||||||
|
# refreshed under the failsafe name
|
||||||
|
# /etc/machine-id, /var/log left alone (see repo memory
|
||||||
|
# "sd-fallback-fstab-clobber")
|
||||||
|
# The bootloader in the SD's first sectors (idbloader/u-boot) is not touched.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
[ "$(id -u)" -eq 0 ] || { echo "Run as root (sudo)." >&2; exit 1; }
|
[ "$(id -u)" -eq 0 ] || { echo "Run as root (sudo)." >&2; exit 1; }
|
||||||
|
|
||||||
SD_ROOT_PART=/dev/mmcblk0p2
|
SD_UUID=39118305-4927-47a4-acc7-ba022f37af22
|
||||||
|
SD_ROOT_PART=/dev/disk/by-uuid/$SD_UUID
|
||||||
MOUNT_POINT=/mnt/sd-backup-root
|
MOUNT_POINT=/mnt/sd-backup-root
|
||||||
|
FAILSAFE='boot-failesafe-rename-to:boot.scr'
|
||||||
|
|
||||||
|
[ -e "$SD_ROOT_PART" ] || { echo "SD card (UUID $SD_UUID) not present." >&2; exit 1; }
|
||||||
|
|
||||||
root_src=$(findmnt -no SOURCE /)
|
root_src=$(findmnt -no SOURCE /)
|
||||||
if [ "$root_src" = "$SD_ROOT_PART" ]; then
|
if [ "$(readlink -f "$SD_ROOT_PART")" = "$root_src" ]; then
|
||||||
echo "Currently booted from $SD_ROOT_PART — refusing to sync SD onto itself." >&2
|
echo "Currently booted from the SD card ($root_src) — refusing to sync SD onto itself." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
root_uuid=$(findmnt -no UUID /)
|
||||||
|
|
||||||
mkdir -p "$MOUNT_POINT"
|
mkdir -p "$MOUNT_POINT"
|
||||||
mounted_here=0
|
mounted_here=0
|
||||||
@@ -41,13 +54,16 @@ trap cleanup EXIT
|
|||||||
# rsync exit 24 ("partial transfer due to vanished source files") is expected on a
|
# 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
|
# 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.
|
# mid-sync. Tolerate that one code; anything else is a real failure and still aborts.
|
||||||
|
# Excluded paths are also protected from --delete (no --delete-excluded), which is
|
||||||
|
# what keeps the SD's failsafe-renamed boot script in place.
|
||||||
rc=0
|
rc=0
|
||||||
rsync -aHAX --numeric-ids --delete \
|
rsync -aHAXx --numeric-ids --delete \
|
||||||
--info=progress2 \
|
--info=progress2 \
|
||||||
--exclude=/proc/* --exclude=/sys/* --exclude=/dev/* --exclude=/run/* \
|
--exclude=/proc/* --exclude=/sys/* --exclude=/dev/* --exclude=/run/* \
|
||||||
--exclude=/tmp/* --exclude=/mnt/* --exclude=/media/* --exclude=/lost+found \
|
--exclude=/tmp/* --exclude=/mnt/* --exclude=/media/* --exclude=/lost+found \
|
||||||
--exclude=/boot/firmware/* --exclude=/swapfile \
|
--exclude=/swapfile \
|
||||||
--exclude=/etc/fstab --exclude=/etc/machine-id --exclude=/var/log/* \
|
--exclude=/etc/fstab --exclude=/etc/machine-id --exclude=/var/log/* \
|
||||||
|
--exclude=/boot/armbianEnv.txt --exclude=/boot/boot.scr --exclude="/boot/$FAILSAFE" \
|
||||||
--stats / "$MOUNT_POINT/" || rc=$?
|
--stats / "$MOUNT_POINT/" || rc=$?
|
||||||
|
|
||||||
if [ "$rc" -ne 0 ] && [ "$rc" -ne 24 ]; then
|
if [ "$rc" -ne 0 ] && [ "$rc" -ne 24 ]; then
|
||||||
@@ -58,4 +74,18 @@ if [ "$rc" -eq 24 ]; then
|
|||||||
echo "Note: some files vanished mid-sync (rsync exit 24) — normal on a live root." >&2
|
echo "Note: some files vanished mid-sync (rsync exit 24) — normal on a live root." >&2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# fstab and armbianEnv.txt: take the source's content, point root at the SD.
|
||||||
|
for f in etc/fstab boot/armbianEnv.txt; do
|
||||||
|
sed "s/$root_uuid/$SD_UUID/g" "/$f" > "$MOUNT_POINT/$f.new"
|
||||||
|
chmod --reference="/$f" "$MOUNT_POINT/$f.new"
|
||||||
|
mv "$MOUNT_POINT/$f.new" "$MOUNT_POINT/$f"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Keep the SD's boot script current but dormant, so U-Boot never boots the SD
|
||||||
|
# while the eMMC is healthy.
|
||||||
|
install -m 0644 /boot/boot.scr "$MOUNT_POINT/boot/$FAILSAFE"
|
||||||
|
if [ -e "$MOUNT_POINT/boot/boot.scr" ]; then
|
||||||
|
echo "WARNING: $MOUNT_POINT/boot/boot.scr exists — U-Boot will boot the SD, not the eMMC." >&2
|
||||||
|
fi
|
||||||
|
|
||||||
echo "SD backup ($SD_ROOT_PART) synced from $root_src."
|
echo "SD backup ($SD_ROOT_PART) synced from $root_src."
|
||||||
|
|||||||
Reference in New Issue
Block a user