Skip to content

Keep the VM image bootable through the firmware after a kernel update - #293

Merged
emirb merged 1 commit into
quattrofrom
vm-image/keep-limine-default-after-reseal
Oct 19, 2026
Merged

emirb merged 1 commit into
quattrofrom
vm-image/keep-limine-default-after-reseal

Conversation

@emirb

@emirb emirb commented Oct 19, 2026

Copy link
Copy Markdown
Contributor

A clone of the nightly VM image stops booting through the firmware after its first initramfs rebuild, which any kernel or mkinitcpio update triggers. Limine's default entry then panics (efi: Failed to open image with path boot():/EFI/Linux/omarchy_linux-omarchy.efi) or stops at Blake2b hash ... does not match! Press Y to continue. It reproduces on the published stable 4.0.5 image with no rc packages.

vm-seal empties /etc/machine-id so each clone gets its own machine ID, but it leaves the build's ID on Limine's boot entry (comment: machine-id=<build ID>), and default_entry: 2 boots that entry. limine-entry-tool and limine-snapper-sync look an entry up by machine ID first, and by name only when it names no machine. So a clone's first limine-mkinitcpio adds a second "Omarchy" entry and leaves the default on the build's:

  • Under vm-boot, which skips the firmware, the rebuild takes the non-UEFI path and deletes the UKI the default entry boots, so the next firmware boot panics.
  • Through the firmware, it writes a new UKI to the same path, so the default entry's hash is stale and Limine stops to ask.
  • Before any rebuild, limine-snapper-sync exits 1 (Target OS name 'Omarchy' not found).

vm-seal now drops the build's machine ID from the entry, so a clone finds it by TARGET_OS_NAME and updates it in place. Clones still get machine IDs of their own.

vm-verify, which gates every nightly publish, now rebuilds the initramfs in its throwaway clone. It checks that the menu's entries stay as they were, that the entry Limine boots by default changed, and that every file it loads is on the ESP with its BLAKE2b. On the published 4.0.5 image four of these checks fail; on the same disk sealed with this change all 24 checks pass.

Installed systems keep their machine ID, so their entry is still found by it and this change doesn't affect them.

@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Install test passed

x86_64 vs quattro aarch64 vs quattro
Result ✅ passed ✅ passed
Build the ISO 122.0 s −15.0 s 308.0 s +3.0 s
Install 86.4 s +2.1 s 135.8 s +0.0 s
First boot 14.9 s +0.9 s 6.6 s +0.0 s
Everyday boot 14.5 s −0.2 s 5.2 s −0.0 s

Boots are loader, kernel and userspace, without the VM's firmware.

Install phases, x86_64
Phase This PR quattro
Preparing live environment 0.2 s 0.2 s
Preparing install target 0 s 0 s
Installing Arch + Omarchy 69.8 s 69.7 s
Configuring hibernation 0.3 s 0.2 s
Configuring system 2.8 s 2.4 s
Staging provisioning 0.2 s 0.2 s
Finalizing Limine boot 9.4 s 8.3 s
Finalizing user 3.5 s 3.1 s
Configuring login 0.1 s 0.1 s
Configuring SSH access 0.2 s 0.2 s
Configuring Tailscale 0 s 0 s
Configuring DNS resolver 0 s 0 s
Validating boot setup 0 s 0 s
Creating factory snapshot 0.1 s 0.1 s
Install phases, aarch64
Phase This PR quattro
Preparing live environment 0.1 s 0.1 s
Preparing install target 0 s 0 s
Installing Arch + Omarchy 115.2 s 117.2 s
Configuring hibernation 0 s 0 s
Configuring system 5.9 s 6.7 s
Staging provisioning 0.1 s 0.3 s
Finalizing Limine boot 9 s 7.4 s
Finalizing user 4.9 s 3.7 s
Configuring login 0.1 s 0.1 s
Configuring SSH access 0.2 s 0.2 s
Configuring Tailscale 0 s 0 s
Configuring DNS resolver 0 s 0 s
Validating boot setup 0.1 s 0.1 s
Creating factory snapshot 0.1 s 0.1 s

Run · bcc3409

vm-seal empties /etc/machine-id, so each clone of the image takes its
own machine ID from the VM's SMBIOS UUID. /boot/limine.conf still names
the build's machine on its one entry ("comment: machine-id=<build ID>"),
and default_entry: 2 boots that entry's UKI. limine-entry-tool and
limine-snapper-sync look an entry up by machine ID first, and by name
only when the entry names no machine (TreeNode.findOsNode in both). So
on a clone:

- The first limine-mkinitcpio, which any kernel or mkinitcpio update
  runs, adds a second "Omarchy" entry for the clone and leaves Limine's
  default on the build's.
- Booted by vm-boot, which skips the firmware, there is no
  /sys/firmware/efi, so the rebuild installs a plain kernel entry and
  deletes omarchy_linux-omarchy.efi, the file the default entry boots.
  The next firmware boot panics in Limine: "efi: Failed to open image
  with path boot():/EFI/Linux/omarchy_linux-omarchy.efi".
- Booted through the firmware, the rebuild writes a new UKI to the same
  path, and the default entry stops at "Blake2b hash ... does not
  match! Press Y to continue" until someone presses a key.
- Before any rebuild, limine-snapper-sync exits 1: "Target OS name
  'Omarchy' not found".

vm-seal now drops the build's machine ID from the entry, so every clone
finds it by TARGET_OS_NAME and updates it in place. Clones keep machine
IDs of their own.

vm-verify rebuilds the initramfs in its throwaway clone and checks that
the menu's entries stay as they were, that the entry Limine boots by
default changed, and that each file it loads is on the ESP with its
BLAKE2b. On the published 4.0.5 image (stable/4.0.5/450) four of the
six new checks fail and the other 20 checks pass; on the same disk
sealed with this change all 24 pass, in 14 s. Two clones of that
image, one rebuilt under vm-boot and one through the firmware, then
booted Limine's default entry to the desktop, with different machine
IDs.
@emirb
emirb force-pushed the vm-image/keep-limine-default-after-reseal branch from 104961c to bcc3409 Compare October 19, 2026 21:56
@emirb
emirb merged commit fd1c9a5 into quattro Oct 19, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant