AlmaLinux 10: Dual EFI + mdadm RAID1 on Bare Metal (or: How I Spent My Friday Evening Arguing With a Boot Loader)

Introduction, or “What Could Possibly Go Wrong”

So you have a perfectly good server. Two perfectly good SATA SSDs. A perfectly reasonable desire to mirror them so that when one inevitably dies at 3am on a Sunday, your server keeps running.

You’ve done this a hundred times. mdadm, RAID1, /boot on the array, done, beer, sleep.

Except it’s 2026, and Red Hat decided that RHEL 10 is UEFI-only (so it is Rocky, Almalinux and so on). Legacy BIOS support has been officially removed. Not deprecated. Not “discouraged”. Removed.

So your old-fashioned “boot from a RAID array” trick? Gone. Because the UEFI firmware needs to read the EFI System Partition before any OS driver loads — which means before mdadm, before LVM, before anything that could make two disks look like one. It needs raw FAT32 on a raw partition, visible to the firmware directly.

To be fair: this is a UEFI spec decision, not a Red Hat invention. Red Hat just stopped pretending it wasn’t a problem.

The bad news is that “stopped pretending” didn’t come with “and here’s an automated solution.” It came with a shrug and a note in the release docs.


“Just Use Hardware RAID” — The Enterprise Answer Nobody Wanted

“But Chris, you have a PowerEdge R640 with a PERC controller. Just use hardware RAID!”

Yes. And maybe you have a system without a PERC. Maybe you have NVMe drives that bypass the PERC entirely. Maybe you prefer software RAID because you like seeing what’s actually happening on your disks without black-box firmware in the way. Maybe you enjoy cat /proc/mdstat and mdadm --detail and being able to do things like add a spare at runtime. Maybe you’re just a person who likes control over their own hardware.

None of these are unreasonable positions.

Red Hat’s answer to all of them is essentially: “We assume you’re running in a cloud, or you have hardware RAID, or this is not our problem.”

Fantastic. Very helpful. Thank you.


The Installer Experience, or: “Meet Anaconda, Your Helpful Friend”

Armed with the AlmaLinux 10 ISO and the knowledge that we need two EFI partitions (one per disk), you boot the installer and navigate to the partitioning screen.

The Anaconda UI, bless its heart, does not let you create a second EFI System Partition on the second disk. It will create one, on one disk, and it is very happy about that. Ask for more? Frowny face.

Fine. There’s a console. Ctrl+Alt+F2. We’ll do it manually.

You open the console and discover that the Anaconda live environment, which is used to install a server operating system that will run production workloads, is missing:

  • which
  • sgdisk
  • gdisk
  • rsync

It does have parted, fdisk, wipefs, and partprobe. That’s something. It also has sfdisk, which turns out to be your best friend because it accepts input non-interactively — essential when you don’t have paste functionality in the console and you’re typing commands by hand on a server that probably lives in a datacenter.

fdisk is there too, but its heredoc handling will try to ask you for the first sector (answering +1G when asked for a sector number returns Value out of range, which is… technically correct and completely unhelpful).

parted works, but will warn you about alignment if you don’t calculate sector boundaries yourself. It’s 2026. We shouldn’t be calculating sector boundaries ourselves.

sfdisk with a one-liner? Gloriously, boringly reliable.


What You Actually Need to Do

Enough complaining (for now). Here’s the setup:

sda: [ sda1: EFI 1GB | sda2: RAID1 member (~893GB) ]
sdb: [ sdb1: EFI 1GB | sdb2: RAID1 member (~893GB) ]
                               ↕ md0
                                /

Two independent EFI partitions. One RAID1 array for /. No separate /boot (RHEL 10 puts the kernel directly under /boot which lives on /). No swap partition — swapfile instead, because life is too short for swap partitions in 2026.


Step-by-Step: The Actually-Works Guide

0. Get to the Console

Boot the AlmaLinux 10 installer. At the Anaconda UI, press:

Ctrl + Alt + F2

You now have a root shell. Welcome to the fun part.

Return to the UI later with Ctrl+Alt+F6.

1. Wipe the Disks

bash
wipefs -a /dev/sda
wipefs -a /dev/sdb

2. Partition Both Disks

sfdisk to the rescue. One line per disk:

bash
printf 'label: gpt\n, 1G, U\n, , R\n' | sfdisk /dev/sda
printf 'label: gpt\n, 1G, U\n, , R\n' | sfdisk /dev/sdb
  • U = EFI System Partition type
  • R = Linux RAID type
  • Alignment is handled automatically. No sector math required.

Verify:

bash
fdisk -l /dev/sda
fdisk -l /dev/sdb

You should see: 1GB EFI partition + ~893GB RAID partition on each disk.

3. Format the EFI Partitions

bash
mkfs.fat -F32 /dev/sda1
mkfs.fat -F32 /dev/sdb1

Ignore the codepage warnings. They’re locale noise. The partitions are fine.

4. Create the RAID1 Array

bash
mdadm --create /dev/md0 \
  --level=1 \
  --raid-devices=2 \
  --metadata=1.2 \
  /dev/sda2 /dev/sdb2

Type y when asked. Format it:

bash
mkfs.ext4 /dev/md0

(ext4 or xfs — both work fine. xfs is the RHEL default. ext4 is the “I’ve been doing this since 2004” choice.)

5. Re-enter the Installer

bash
partprobe && udevadm settle

Then Ctrl+Alt+F6Rescan Disks in the Anaconda storage screen.

6. Assign Mount Points in Anaconda UI

  • /dev/sda1EFI System Partition, mount: /boot/efi
  • /dev/sdb1EFI System Partition, mount: /boot/efi2 (or leave unformatted — just make sure Anaconda knows it’s an ESP so it doesn’t panic)
  • /dev/md0 → mount: /
  • Swap → nothing — we’ll do a swapfile post-install

Proceed with install.


Post-Install Steps

Boot into your fresh AlmaLinux 10 system and SSH in.

1. Sync sdb1 EFI Content from sda1

bash
yum install rsync -y   # yes, rsync isn't installed by default either

rsync -av /boot/efi/ /boot/efi2/

2. Register the sdb UEFI Boot Entry

bash
efibootmgr --create --disk /dev/sdb --part 1 \
  --label "AlmaLinux (sdb)" \
  --loader '\EFI\almalinux\shimx64.efi'

Set boot order so sda is primary, sdb is fallback:

bash
efibootmgr --bootorder 0003,0004,0000,0001,0002
# adjust boot entry numbers to match your efibootmgr -v output

Verify with efibootmgr -v.

3. Create Swapfile

bash
dd if=/dev/zero of=/swapfile bs=1M count=8192
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab

4. Save mdadm Config and Rebuild initramfs

bash
mdadm --detail --scan >> /etc/mdadm.conf
dracut --force

This step is critical. Without the mdadm config baked into the initramfs, your system may not find the RAID array on boot.

Verify it made it in:

bash
lsinitrd | grep mdadm

You should see etc/mdadm.conf and usr/sbin/mdadm in the output.

5. Automate EFI Sync (The Part Red Hat Forgot to Include)

Every kernel update, every grub update, every shim update — anything that touches /boot/efi/ needs to be mirrored to /boot/efi2/. Red Hat does not do this for you.

So we do it ourselves, with a systemd path unit:

bash
cat > /etc/systemd/system/efi-sync.service << 'EOF'
[Unit]
Description=Sync EFI to sdb fallback

[Service]
Type=oneshot
ExecStart=rsync -a --delete /boot/efi/ /boot/efi2/
EOF

cat > /etc/systemd/system/efi-sync.path << 'EOF'
[Unit]
Description=Watch /boot/efi for changes

[Path]
PathChanged=/boot/efi
Unit=efi-sync.service

[Install]
WantedBy=multi-user.target
EOF

systemctl enable --now efi-sync.path

This fires rsync every time /boot/efi is modified. Automatic. Silent. The way it should have been from the start.


Verify Everything

bash
cat /proc/mdstat          # RAID status — should show [UU]
mdadm --detail /dev/md0   # Full RAID detail
swapon --show             # Swap active
df -h                     # Filesystem layout
efibootmgr -v             # Both boot entries present

A healthy system looks like this:

md0 : active raid1 sdb2[1] sda2[0]
      936492672 blocks super 1.2 [2/2] [UU]

Two Us. That’s the sound of redundancy.


Failover Test

This is important. Don’t skip it.

Go into your BIOS/iDRAC/iLO, change the boot order to put sdb first, reboot. If the system comes up cleanly from sdb, your fallback EFI works. Change the boot order back.

Now you can sleep at night.


Conclusions, or “Thanks UEFI, Very Cool”

What we’ve built here is correct, reliable, and battle-tested. Two independent boot paths, RAID1 for the data, automatic EFI sync, proper initramfs.

What we’ve also built is something that:

  • Required dropping to an installer console that’s missing basic tools
  • Required manually partitioning disks because the GUI won’t create a second ESP
  • Required writing our own sync automation because the OS vendor didn’t provide one
  • Required about an hour of troubleshooting, some creative cursing, and this blog post

None of this is magic. None of it is hard — once you know what to do. But there is exactly zero documentation from Red Hat saying “here’s how you set up software RAID with dual EFI on bare metal.” Because in their world, you’re either in a cloud VM or you have a hardware RAID card.

The rest of us will be here, writing systemd path units and being fine.