fix(disk): enable ext4 verity on the custom-layout path too, or composefs cannot work there - #13
Conversation
…sefs cannot work there The two format paths disagree about ext4: format.go FormatRoot mkfs.ext4 -F -L root -O verity (auto-partition) custom.go formatPartition mkfs.ext4 -F (customMounts) FormatRoot already carries a comment explaining why the flag is required — bootc's --composefs-backend calls FS_IOC_ENABLE_VERITY on individual objects as it writes them, and ext4 only permits that when the feature was set at mkfs time, since it cannot be enabled afterwards. formatPartition never got it. So composefs works on the auto-partition path and is silently impossible on the custom-layout path, though the recipes differ only by customMounts. It surfaces as error: Installing to filesystem: ... Finalizing object tempfile: Enabling verity on tmpfile: Filesystem does not support fs-verity deep in the deploy, AFTER the target has been formatted and the image pulled. This hits precisely the callers most likely to need composefs: every host that installs into pre-existing partitions rather than repartitioning a disk uses customMounts exclusively. For those hosts "do not touch the rest of the disk" is the whole product premise, and they were the ones that could never use composefs. Found by an installer running its first real end-to-end install against a real disk. Every producer-side test and `fisherman validate` accepted the recipe, because it is a valid recipe. The feature flag is inert on non-composefs installs. Test asserts the flag directly and was confirmed to fail without the fix rather than merely passing with it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VvyH2muGbDWLmmmtrPNkwG
|
CI is red on this PR, and none of it is from this change — Failing here: Neither failure is in code this PR touches:
I checked rather than assumed, because "pre-existing" is easy to claim and easy to be wrong about. Locally, against unmodified On this branch specifically: And the new test is discriminating, not decorative — reverting just the one-line fix makes it fail with Happy to rebase once |
|
Merging on a green baseline now that #14 has landed: The VM matrix legs are still red, for a cause that has nothing to do with this change — the Merging with an admin override for that reason, stated plainly rather than quietly. The change itself is corroborated twice over: the same fix is already merged in tuna-os#70, and it is what unblocked a real end-to-end composefs install (7.3 GB deployed, ESP firmware preserved) in tuna-os/bootc-installer-asahi#43. |
The two format paths disagree about ext4:
format.goFormatRootmkfs.ext4 -F -L root -O veritycustom.goformatPartitionmkfs.ext4 -FFormatRootalready carries a comment explaining why the flag is required: bootc's--composefs-backendcallsFS_IOC_ENABLE_VERITYon individual objects as it writes them, and ext4 only permits that when the feature was set at mkfs time — it cannot be enabled afterwards.formatPartitionnever got it.So composefs works on the auto-partition path and is silently impossible on the custom-layout path, even though the two recipes differ only by
customMounts. It surfaces as:deep inside the deploy — after the target has been formatted and the image pulled.
Why this matters more than the diff suggests
It hits exactly the callers most likely to need composefs. Every host that installs into pre-existing partitions rather than repartitioning a whole disk uses
customMountsexclusively — an Apple Silicon installer placing Linux beside macOS, and wootc placing it beside Windows. For those, "don't touch the rest of the disk" is the entire product premise, and they were the two that could never use composefs.It also interacts with bootloader choice, which is how it surfaced: bootc only honours
--bootloader systemdon the composefs path (the ostree path requires bootupd). Apple Silicon needs systemd-boot, because the m1n1 → U-Boot → EFI chain has no persistent EFI variables for grub2 to write an entry into. So there, composefs is not a preference — it is the only viable combination, and this blocked it.Provenance
Found by an installer running its first real end-to-end fisherman install against a real disk (tuna-os/bootc-installer-asahi#26). Every producer-side assertion and
fisherman validateaccepted the recipe, because it is a valid recipe — only executing the install surfaced it.Worth noting a related gap while you're here:
customMountsappears only inrecipe.go,custom.go, and their unit tests — nothing undertests/or.github/workflows/exercises it, so the manual-layout path has no E2E coverage at all. That is why this survived, and why it was found downstream. Written up as tuna-os#71.Risk
The feature flag is inert on non-composefs installs — a little superblock space, no behaviour change unless verity is requested.
Verification
go build ./...andgo test ./internal/disk/pass. The new test asserts the flag directly and was confirmed to fail without the fix (args = [-F /dev/sda3]), not merely to pass with it.The same change is already merged in tuna-os/fisherman (tuna-os#70) and is what unblocked a real composefs install end to end.
🤖 Generated with Claude Code
https://claude.ai/code/session_01VvyH2muGbDWLmmmtrPNkwG