Fix btrfs-subvolume install aborting at 99% after root GPT retag - #9
Fix btrfs-subvolume install aborting at 99% after root GPT retag#9joshmccall221 wants to merge 1 commit into
Conversation
|
Validated live end-to-end on a real machine (Snow Linux live ISO → install to internal NVMe). Before the fix: install died at step 7/8 (99%) with: Root cause confirmed on-disk: after the GPT retag, root was remounted with empty options, exposing the btrfs top-level, so With this patch: a full install (btrfs + subvolumes, systemd-boot, composefs backend, no encryption) completed all 8 steps: Post-install verification of the NVMe: composefs deploy present under The remount now preserving |
|
bootcrew vm tests expected to fail |
There was a problem hiding this comment.
Pull request overview
Fixes a btrfs subvolume install regression where the root filesystem was remounted without subvol=@ after retagging the root GPT type for systemd-boot auto-discovery, causing post-install steps (e.g., hostname/flatpak writes through state/deploy) to fail and abort the install at 99%.
Changes:
- Introduces a shared
disk.RemountRoot(...)helper to remount the root partition with the correct btrfs subvolume options when applicable. - Hoists the btrfs root mount options into a shared constant to avoid drift between mount sites.
- Adds a regression unit test to assert the remount uses
subvol=@,compress=zstd:1for btrfs-subvolume installs and no opts otherwise.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| fisherman/internal/disk/format.go | Adds shared btrfs root mount options constant and RemountRoot helper; reuses the constant in SetupBtrfsSubvolumes. |
| fisherman/internal/disk/format_test.go | Adds TestRemountRoot regression coverage for btrfs-subvolume vs non-subvolume remount behavior. |
| fisherman/cmd/fisherman/main.go | Switches retag post-step to use disk.RemountRoot and preserve btrfs subvolume mount options. |
| CHANGELOG.md | Documents the bug fix and its user-visible impact in the Unreleased changelog. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // BtrfsRootMountOpts are the mount options used for the root btrfs subvolume | ||
| // layout (@, @home, @snapshots). The installed system's state/deploy tree lives | ||
| // inside the @ subvolume, so any (re)mount of the root partition that post-install | ||
| // steps write through must use these options; a bare mount would expose the | ||
| // btrfs top-level instead, where state/deploy does not exist. |
| no such file or directory", aborting the install at 99%. The remount now | ||
| reuses the `subvol=@,compress=zstd:1` options via the new | ||
| `disk.BtrfsRootMountOpts` constant. |
|
GPT-5.6-sol review: |
|
Looks great - fix the conflicts please. |
On btrfs installs with subvolumes, `SetupBtrfsSubvolumes` mounts the target
with `subvol=@`, and the composefs deployment (`state/deploy`) lives inside the
`@` subvolume. After `bootc install`, the root partition is retagged to the
Linux root GPT type for systemd-boot GPT auto-discovery, which requires
unmounting and remounting the root. That remount passed empty mount options, so
it exposed the btrfs top-level instead of the `@` subvolume.
Post-install steps that write through `state/deploy` (WriteHostname, system
Flatpak copy) then failed with:
finding composefs deploy etc: reading composefs deploy base
/mnt/fisherman-target/state/deploy: no such file or directory
aborting the install at step 7/8 (99%) with a fully-written but unconfigured
system on disk.
Remount the root with `subvol=@,compress=zstd:1` (the same options
`SetupBtrfsSubvolumes` uses) when the install uses btrfs subvolumes. The options
are hoisted into a shared `disk.BtrfsRootMountOpts` constant so the initial
mount and the retag remount cannot drift apart, and the remount is extracted
into a testable `disk.RemountRoot` helper.
Regression test `TestRemountRoot` asserts the btrfs-subvolume remount carries
`subvol=@` while non-subvolume installs remount bare.
b50eb02 to
704ffb3
Compare
|
For the record this fix is "valid" but not currently useful because the subvol support isn't wired in fisherman. Will create tracking issue and update here. |
Problem
On btrfs installs with subvolumes, a fresh install aborts at step 7/8 (99%) — right after
bootc installcompletes — with:The OS is fully deployed on disk (composefs deploy, systemd-boot, UKI, loader entry all present), but the system is left unconfigured (no hostname written) and the installer reports failure.
Root cause
SetupBtrfsSubvolumesmounts the target withsubvol=@, and the composefs deployment (state/deploy/<hash>) lives inside the@subvolume.After
bootc install, for systemd-boot + composefs installs the root partition is retagged to the Linux-root GPT type for GPT auto-discovery. This unmounts and remounts the root — but the remount passed empty mount options:So the root is remounted at the btrfs top-level instead of the
@subvolume. Post-install steps that write throughstate/deploy(WriteHostname, system Flatpak copy) then look at the top-levelstate/, which has nodeploy/, and fail. The inline comment on that block ("…the empty /boot/efi directory in the XFS root") shows the path was written/validated for XFS and regressed on btrfs-subvolume layouts.Fix
Remount the root with the same options
SetupBtrfsSubvolumesused (subvol=@,compress=zstd:1) when the install uses btrfs subvolumes. To keep the two mount sites from drifting:disk.BtrfsRootMountOptsconstant (used by bothSetupBtrfsSubvolumesand the retag remount).disk.RemountRoot(diskDev, partNum, target, btrfsSubvols)helper.Non-btrfs-subvolume installs (xfs/ext4) remount bare exactly as before.
Test
Adds
TestRemountRoot, asserting the btrfs-subvolume remount carriessubvol=@(andcompress=zstd:1) while non-subvolume installs remount with no options.