Skip to content

4.1.0 — Apple Silicon first: the M2 Max restore, one restore pipeline, a test bed that needs no spare drive

Choose a tag to compare

@doug445 doug445 released this 19 Sep 03:35
· 4 commits to main since this release

4.1.0 — Apple Silicon first: the M2 Max restore, one restore pipeline, a test bed that needs no spare drive

Found on the M2 Max, fixed

  • Fedora Asahi Remix: shim on the removable path had no GRUB beside it.
    restore-rebuild-boot.sh took os-release's ID for the ESP's vendor
    directory. Asahi has ID=fedora-asahi-remix and ships its loaders in
    EFI/fedora, so the Fedora-shim branch was never taken, grub2-install
    was tried (and refused, on an EFI Secure Boot build), and EFI/BOOT/BOOTAA64.EFI
    (shim) was left with no grubaa64.efi to load: the restored system stopped
    at Failed to open \EFI\BOOT\grubaa64.efi. Caught by the test bed's VM boot
    before any reboot. The rebuild now finds the directory that actually holds
    this arch's shim or GRUB (ID, each ID_LIKE token, then whichever
    directory has a shim, then one with a GRUB image; never EFI/BOOT), and
    testbed.sh finish checks the removable path's shim has its GRUB beside it
    before it lets anyone boot. Seven x86 bare-metal restores had passed without
    exercising this.
  • The VM boot on aarch64 had no display: -vga std is not an option of
    the virt machine. It gets a virtio-gpu-pci there.

The restore test bed without a spare drive

  • TB_TARGET_IMAGE=<file> — a sparse disk image on the backup drive (no
    CoW, never on one of this machine's own disks), attached as a loop device
    and used exactly like a test drive: partitioned like the host, LUKS with the
    host's KDF, restored, fingerprinted, booted in a VM. A file is nothing the
    firmware can boot, so its verdict is PASS-VM from testbed.sh collect --vm: proof of the restore, not of the Bare-metal restore column, which
    stays ⚠️ until a drive has really booted.
  • TB_TARGET_ESP=<PARTUUID> — the same-disk mode for machines whose
    firmware boots nothing external (Apple Silicon): a spare ESP on the running
    disk plus the free space after it — on a Mac, the ESP of a second "UEFI
    environment only" Asahi install. The test bed adds its partitions there
    (explicit numbers and sectors, one sgdisk call each, the free region
    re-verified at write time, partx -a because a disk in use cannot re-read
    its table, never a zap), keeps the ESP and its stub files (only EFI/ is
    cleared), and the restored system is picked at power-on. The boot logger
    then goes by partition PARTUUID, not disk serial; U-Boot's ubootefi.var
    (this machine's boot order, restored onto the spare ESP) is parked so the
    stub boots its own ESP; the restored boot chain is checked to name test
    partitions only; the VM boot gets a read-only device-mapper disk made of the
    test partitions alone under a GPT with their real PARTUUIDs and the disk's
    sector size; TB_DELETE_TARGET=1 testbed.sh revert removes the partitions
    (never the ESP). Written and unit-tested; not yet run on metal — it needs
    the second stub installed from macOS.
  • TB_BACKUP_MOUNT=<mount> — the test archive goes to another mounted
    drive (another machine's production backup drive plugged in for the test);
    the suite's wrong-drive guard is told that drive's UUID for the test only.
  • 4096-byte-sector targets: the VM's virtual disk now carries the
    target's logical sector size (Apple NVMe is 4Kn; at 512 the GPT is read at
    the wrong offsets).
  • The USB transfer-size workaround (TB_SECTORS_KB) applies to USB drives
    only — no longer to NVMe, SATA or loop devices.

One restore pipeline: lib-restore.sh

borg-restore.sh and backintime-restore.sh carried 1,100 identical lines
each, and they had drifted: Back In Time's copy lacked the volume-group name
bridge, the tolerance for an ESP GRUB stub with no grub.cfg, and the check
that a Debian initramfs carries the root container's crypttab entry. The shared
pipeline — target checks, the new disk's ids, fstab / crypttab / command-line
rewrite, swapfiles and the SELinux relabel, the chroot boot rebuild, the
verification — is now lib-restore.sh, eleven stages both front ends run in
order. The front ends keep what differs: archive or snapshot selection and
the extraction. Installed to /usr/local/sbin and copied to the backup
drive's recovery-scripts/ with the rest. Proven by the M2 Max restore, which
ran the refactored pipeline.

The README, split

The README is 200 lines: what it is, the quick start, Apple Silicon, the
status summary, restore, the documentation table. Everything else moved
verbatim into docs/: STATUS.md (the tested / untested tables, the test
bed, what is not yet universal), INSTALL.md (deploy, drive set-up and
sizing, dependencies, scheduling, retention, the tray, every file),
RESTORE.md, TROUBLESHOOTING.md (logs, the report, USB bridge drops,
hand-rolling a fix), LAYERS.md, FAQ.md. Every cross-reference in
CONTRIBUTING, SECURITY, the issue templates and the scripts' own hints was
repointed. deploy.sh copies RESTORE.md and TROUBLESHOOTING.md to the
backup drive's recovery-scripts/ too.

The report a new setup is added from

backup-diag.sh opens with a setup fingerprint: one screen of the facts
every decision is made from, gathered without assuming any of them —
ID/ID_LIKE, which package managers exist (apt, dnf, zypper, pacman, apk,
xbps, emerge, slackpkg, nix, eopkg, rpm-ostree, …), the root filesystem and
the whole device stack under it, every real filesystem mounted (the fixed
type list that filtered an unknown root filesystem out of its own report is
gone), what the kernel supports, page and sector sizes, encryption and
volume management, the ESP's vendor directories and U-Boot's variable file
where there is one, every loader config found, the initramfs tools, what
could take snapshots — then the mkfs/fsck/tooling each filesystem has. That
section plus What the suite's own detection reports is what a distro,
filesystem or boot layout the suite has never met is added from, with nothing
else needed from the machine. "Universal" is the goal; this is how a report
from a setup nobody here owns turns into a fix.

Apple Silicon, said plainly

The FAQ now says what "run the Asahi installer from macOS" depends on — Apple
still serving the stub macOS image for that model — and what to protect on a
Mac that will outlive its macOS support: never delete the stub container,
keep macOS bootable (the installer runs from it and finishes in
recoveryOS), count on a restore over the existing
boot chain
, and consider a second stub while Apple still serves the image.