scripts-fabq/notes/update-efi-mirror.md
Fabrice Quenneville b098c94e19 feat: add redundant root with EFI mirror setup guide
Covers disk formatting, BTRFS RAID1 conversion, fstab configuration,
and the update-efi-mirror script with apt post-install hook setup.
Includes a separate procedure for migrating to a new disk.
2026-05-17 04:47:26 -04:00

8.6 KiB

Redundant Root with EFI Mirror

Table of Contents

Overview

This setup provides a redundant Debian root drive using BTRFS RAID1 across two disks, with a synced EFI partition on both so the machine can boot from either. The script update-efi-mirror keeps the backup EFI in sync and re-installs GRUB on both physical disks. It is triggered automatically after every apt operation.

Placeholders

Replace the placeholders below with the appropriate values for your setup:

  • Devices

    • Primary disk: <primary-disk> (e.g., /dev/sda, /dev/nvme0n1)
    • Backup disk: <backup-disk> (e.g., /dev/sdb, /dev/nvme1n1)
    • Primary EFI partition: <primary-efi-part> (e.g., /dev/sda1, /dev/nvme0n1p1)
    • Backup EFI partition: <backup-efi-part> (e.g., /dev/sdb1, /dev/nvme1n1p1)
    • Primary root partition: <primary-root-part> (e.g., /dev/sda2, /dev/nvme0n1p2)
    • Backup root partition: <backup-root-part> (e.g., /dev/sdb2, /dev/nvme1n1p2)
    • Primary swap partition: <primary-swap-part> (e.g., /dev/sda3, /dev/nvme0n1p3)
    • Backup swap partition: <backup-swap-part> (e.g., /dev/sdb3, /dev/nvme1n1p3)
  • UUIDs

    • Primary EFI UUID: <primary-efi-uuid> (e.g., D167-0F46)
    • Backup EFI UUID: <backup-efi-uuid> (e.g., 08E8-A87C)
    • Root BTRFS UUID: <root-uuid> (e.g., 387526ec-f3bd-4fa8-a17e-e985121ada0b)
    • Primary swap UUID: <primary-swap-uuid>
    • Backup swap UUID: <backup-swap-uuid>

How It Works

  • The root filesystem is BTRFS RAID1 across two partitions. Either disk alone can serve reads and writes.
  • Each disk has its own EFI partition. GRUB is installed on both physical disks.
  • After every apt install or upgrade, an apt hook calls update-efi-mirror, which:
    1. Rsyncs the live /boot/efi to the backup EFI partition.
    2. Runs grub-install on both physical disks.
  • Either disk can be removed and the system will still boot and run.

Paths

  • Sync script: /usr/local/sbin/update-efi-mirror
  • Apt hook: /etc/apt/apt.conf.d/99-update-efi-mirror
  • fstab: /etc/fstab

Setup Procedure

1. Format the Disks

Verify which disks are present before touching anything

lsblk
lsblk -f

Open fdisk on the backup disk

If the disk was previously used at a smaller capacity, the GPT backup table may be misaligned — fdisk will correct it on write.

fdisk <backup-disk>

Create a GPT partition table if not already present:

g

Check the primary disk partition layout and note the exact sector boundaries

fdisk -l <primary-disk>

This shows the Start and End sectors for each partition. Use these values when partitioning the backup disk so the layouts match exactly.

Create the three partitions to match the layout of the primary disk

# Size Type
1 830M EFI System
2 ~12G Linux fs
3 Remainder Linux swap

Inside fdisk, the sequence is:

n          # new partition
            # enter the exact End sector from the primary disk to match partition sizes
t          # change type
1          # select partition 1
EFI System # set type to EFI
t          # change type
3          # select partition 3
Linux swap # set type to swap
w          # write and exit

Partition sizes must be at least as large as the corresponding primary partition — the BTRFS replace will fail if the target partition is smaller than the source.

Format the new EFI partition

apt install dosfstools   # if not installed
mkfs.fat -F32 <backup-efi-part>

Format the new swap partition

mkswap <backup-swap-part>

Check UUIDs of the new partitions

lsblk -f <backup-disk>

2. Convert the Root Filesystem to BTRFS RAID1

Add the backup partition to the BTRFS volume

btrfs device add <backup-root-part> /

Convert to RAID1

btrfs balance start -mconvert=raid1 -dconvert=raid1 /

Monitor the balance:

btrfs balance status /

Verify the final layout

btrfs filesystem show /
btrfs fi usage /

3. Configure fstab

Edit /etc/fstab to mount the primary EFI partition normally and document the backup EFI UUID in a commented-out entry. The script reads the backup UUID from this comment.

Edit fstab

nano /etc/fstab

The fstab should contain:

# Primary EFI — mounted at boot
UUID=<primary-efi-uuid>  /boot/efi  vfat  umask=0077  0  1

# Backup EFI — not auto-mounted, used by update-efi-mirror
#UUID=<backup-efi-uuid> /boot/efi vfat umask=0077 0 1

# Root — BTRFS RAID1 (both partitions share the same UUID)
UUID=<root-uuid>  /  btrfs  defaults,noatime  0  1

# Swap — both disks
UUID=<primary-swap-uuid>  none  swap  sw  0  0
UUID=<backup-swap-uuid>   none  swap  sw  0  0

The backup EFI line must start with #UUID= — this is the format the script greps for:

grep "^#UUID=" /etc/fstab | grep "/boot/efi"

Reload systemd after editing fstab

systemctl daemon-reload

4. Install the Sync Script

Create the script

nano /usr/local/sbin/update-efi-mirror

Paste the contents of update-efi-mirror.sh.

Set ownership and permissions

chown root:root /usr/local/sbin/update-efi-mirror
chmod 755 /usr/local/sbin/update-efi-mirror

The script will:

  1. Detect the currently mounted EFI partition and its disk.
  2. Read the backup EFI UUID from the #UUID= comment in /etc/fstab.
  3. Mount the backup EFI to a temp directory, rsync all files from the live EFI, then unmount.
  4. Run grub-install --recheck on both physical disks.

5. Configure apt to Run the Script Post-Install

Create the apt hook

nano /etc/apt/apt.conf.d/99-update-efi-mirror

Add:

DPkg::Post-Invoke {"if [ -x /usr/local/sbin/update-efi-mirror ]; then /usr/local/sbin/update-efi-mirror; fi";};

This runs the sync script after every apt operation that invokes dpkg — including kernel upgrades, which update /boot/efi with new initramfs and GRUB config.

6. Test

Run the script manually

/usr/local/sbin/update-efi-mirror

Expected output:

Syncing EFI files: <primary-efi-uuid> -> <backup-efi-uuid>
EFI Files Sync Complete.
Updating GRUB bootloader on both physical disks...
Redundancy Complete: Files synced and GRUB updated on <primary-disk> and <backup-disk>.

Test the apt hook

apt update
apt upgrade -y

The sync output should appear at the end of the upgrade, after GRUB regenerates its config.

Verify the backup EFI contents match

TMPMNT=$(mktemp -d)
mount -U <backup-efi-uuid> "$TMPMNT"
diff -r /boot/efi/ "$TMPMNT/"
umount "$TMPMNT"
rmdir "$TMPMNT"

Verify GRUB is installed on both disks

fdisk -l <primary-disk> | grep -i efi
fdisk -l <backup-disk>  | grep -i efi

Optional Boot from the backup disk

Swap the boot order in BIOS/UEFI to confirm the machine boots cleanly from <backup-disk>.

Moving to a New Disk

Use this procedure when replacing one of the two disks in the BTRFS RAID1 — for example when upgrading to a larger drive.

1. Partition the new disk following Step 1.

2. Find the device ID of the partition to be replaced:

btrfs filesystem show /

3. Shrink the filesystem on the disk being replaced to fit the new partition:

btrfs filesystem resize <device-id>:<size> /

4. Replace the old partition with the new one:

btrfs replace start <device-id> <new-root-part> /
btrfs replace status /

5. Grow the new partition to max:

btrfs filesystem resize <device-id>:max /

6. Update fstab if the backup EFI UUID has changed (new disk = new EFI UUID):

lsblk -f <new-disk>
nano /etc/fstab
systemctl daemon-reload

7. Run the sync script to install GRUB on the new disk and populate its EFI partition:

/usr/local/sbin/update-efi-mirror

8. Verify following Step 6.