Skip to content

Clear disk signatures before archinstall wipes the target - #138

Open
mp-c0de wants to merge 1 commit into
omacom:quattrofrom
mp-c0de:fix-full-disk-wipe-existing-luks
Open

Clear disk signatures before archinstall wipes the target#138
mp-c0de wants to merge 1 commit into
omacom:quattrofrom
mp-c0de:fix-full-disk-wipe-existing-luks

Conversation

@mp-c0de

@mp-c0de mp-c0de commented Aug 30, 2026

Copy link
Copy Markdown

Fixes #137.

A Full Install / erase the entire disk onto a drive that already held a LUKS partition aborted during Installing Arch + Omarchy, with archinstall raising a SysCallError when /usr/bin/wipefs --all /dev/sda2 exited 1. Running wipefs -a /dev/sda by hand from the recovery shell and re-running the identical install made it succeed.

Cause

omarchy-iso-cleanup-disk unmounts, swapoffs, deactivates LVM, closes open crypt mappings, then flushes and re-reads the table. All of that releases holders; none of it removes anything written on the disk. A LUKS header on an unopened partition is not a holder, so nothing in the cleanup touches it, and archinstall's own per-partition wipefs --all becomes the first command to meet a stale header — mid-install, where failing is expensive.

The net effect is that "wipe the entire disk" is never carried out by our own code. It is delegated to archinstall's per-partition wipe, which is the fragile path; the manual whole-disk wipefs -a works because it addresses the disk instead.

Change

After the existing holder-release loops, wipefs -af each partition and then the disk. Partitions first, because the table is what makes the child nodes addressable — taking the disk first would strand the old headers in space nothing can name. Failures are tolerated on purpose: the whole-disk wipe that follows takes the GPT, its backup header and the PMBR with it, which is what makes a partition whose own wipe just failed stop existing. That is the manual recovery step, done for the user this time.

No new dependency. wipefs is util-linux and is demonstrably on the medium, since archinstall's own call to it is what fails.

This cannot reach a disk the user did not ask to erase. The orchestrator skips cleanup entirely when ctx.is_protected, and _install_disk() returns a device only when its modification carries wipe: true (phases_impl.py:180-193), so dual-boot, protected and pre-mounted installs never call it.

Verification

On a loop-backed disk built to the same shape as the reported failure — GPT, vfat p1, LUKS2 p2 — under Debian with util-linux 2.38.1 and cryptsetup 2.6.1.

Before, the cleanup reports success and changes nothing:

--- signatures remaining on the whole disk ---
   loop0  0x200      gpt
   loop0  0x1ffffe00 gpt
   loop0  0x1fe      PMBR
--- signatures remaining on /dev/loop0p2 ---
   loop0p2 0x0    crypto_LUKS 94aa1812-b41d-4c95-9385-6cd2dec6824d
   loop0p2 0x4000 crypto_LUKS 94aa1812-b41d-4c95-9385-6cd2dec6824d

After:

   /dev/loop0p1: 8 bytes were erased at offset 0x00000036 (vfat)
   /dev/loop0p2: 6 bytes were erased at offset 0x00000000 (crypto_LUKS)
   /dev/loop0p2: 6 bytes were erased at offset 0x00004000 (crypto_LUKS)
   /dev/loop0: 8 bytes were erased at offset 0x00000200 (gpt)
   /dev/loop0: 8 bytes were erased at offset 0x1ffffe00 (gpt)
   /dev/loop0: 2 bytes were erased at offset 0x000001fe (PMBR)
--- signatures remaining on the whole disk ---
   (none)

Both LUKS2 headers, both GPT copies and the PMBR are gone, and the disk is empty — the same end state as the manual workaround.

Also checked, all unchanged: the script stays idempotent (three consecutive runs, including against a bare disk with no table, exit 0), --protected mode still returns before any of this, and both argument guards still exit 1.

./test/all behaves identically before and after this branch on my machine. One case, "the failure screen shows the diagnosis", fails in both — it needs gum, which isn't installed here — so it is a local environment gap, not a regression.

Not added: a unit test. test/all is deliberately VM-free and unprivileged, and the only honest test of this code needs a real block device — a stubbed one would have to name a real disk to satisfy the script's [[ -b $disk ]] guard, and if the stubbing ever broke it would run wipefs against the developer's own drive. The reproduction above is scripted and I'm happy to contribute it under test/integration.d/ instead if you'd like it there.

The full-disk cleanup released holders but never removed anything written
on the disk, so a previous install's LUKS header reached archinstall
intact. Archinstall's own per-partition wipefs --all was the first command
to touch it, and when that failed the install aborted mid-run after the
user had already asked for the whole disk to be erased.

Wipe each partition's signatures and then the disk's own, which takes the
GPT, its backup header and the PMBR with it. Only the wipe path reaches
this script, so the whole disk is in scope by construction.
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.

Full Install aborts when the target disk already holds a LUKS partition

1 participant