| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
|
One thing I want to flag proactively for the reviewer: The BLS probe here reads /boot/loader/entries in the host mount But it introduces an implicit dependency on that host mount being let bls_present = esp_mount.fd.metadata("loader/entries")
.map(|m| m.is_dir())
.unwrap_or(false);That's namespace-safe and doesn't rely on external mount ordering. Happy to switch to the ESP-mount version if you'd prefer that Assisted-by: Claude (Opus 4) |
Sorry, something went wrong.
|
Small tidy-up force-pushed as 2e421b5: consolidated the new tests into the existing mod tests at the bottom of the file (every other .rs in the tree has exactly one mod tests; my initial submission was the only file with two). No functional change; the 9 tests still pass on aarch64 (cargo test --release --lib -p bootc-lib bootc_composefs::status) and bootc status still returns the healthy BootcHost YAML with bootType: Bls on the Pi 5 target. |
Sorry, something went wrong.
There was a problem hiding this comment.
The logic looks good, but tests for grub-cc failing
Sorry, something went wrong.
|
@Johan-Liebert1 thanks for the review — you're right, root cause diagnosed. My refactor accidentally changed the caching semantics: the original get_bootloader() had an early-return path that bypassed the OnceLock cache on EFI systems, and I collapsed that into unconditional caching when I did the classifier-split refactor. That broke grub-cc tests because the tap.nu is_composefs() helper (called from every readonly test) reads bootc status --json and hits the booted: null case when the bootloader-detection cache holds a stale value. Reworking now to preserve the pre-existing "don't cache on EFI" behavior; the non-EFI BLS-probe path (the actual point of the PR) will still cache since the FS-probe result is stable. Will force-push shortly. Assisted-by: Claude (Opus 4) |
Sorry, something went wrong.
|
Force-pushed as 34ea3cb. Fix preserves the pre-existing "don't cache on EFI" semantics: get_bootloader() now caches only when the classification came from the FS-probe path (i.e., SystemNotUEFI / MissingVar). On EFI systems, EFI_LOADER_INFO is re-read every call, matching the original early-return behavior that grub-cc TMT plans depend on. Diff shape unchanged (crates/lib/src/bootc_composefs/status.rs only; +138/-21 including the classifier-split refactor and its table-driven unit test). Let CI re-run and confirm grub-cc goes green. Assisted-by: Claude (Opus 4) |
Sorry, something went wrong.
|
The Grub CC failures are unrelated to this PR. See #2378 I see Claude's hallucinating again :) |
Sorry, something went wrong.
|
Update: the 4 CI failures on this PR (test-upgrade (fedora-44, composefs) and the three grub-cc variants) turn out to be pre-existing failures on main, not caused by this PR. Same 4 jobs are red on the release PR #2377 and the Renovate bump PR #2373 — both of which have no code changes in this area:
Compared to the last fully-green PR (#2363, merged 2026-08-07), something between then and 2026-08-09 broke these tests on main. Happy to help track that down separately if useful — but this PR isn't the trigger. Live verification of this PR on aarch64 (Raspberry Pi 5, direct-kernel boot from Pi firmware, no UEFI at runtime):
Reworked commit at 34ea3cb preserves the pre-existing "don't cache on EFI" semantics of get_bootloader() (caches only when classification came from the FS-probe path, i.e. non-EFI / filesystem-stable state). Should be safe to review on its merits. Assisted-by: Claude (Opus 4) |
Sorry, something went wrong.
|
Ah, ninja'd — hadn't seen #2378 when I posted the timeline. Same conclusion, thanks for tracking it separately. |
Sorry, something went wrong.
Addresses review feedback on bootc-dev#2376: a legacy BIOS system that has a BLS entries directory would be classified as `Bootloader::Systemd` even though GRUB may still own the boot flow. That is a real configuration, not a hypothetical one. GRUB reads Type 1 entries itself via the `blscfg` module, and Fedora and RHEL enable that by default with `GRUB_ENABLE_BLSCFG=true`. So a legacy-BIOS Fedora or RHEL install has BOTH `/boot/grub2/` and `/boot/loader/entries/`, and the BLS probe alone cannot tell it apart from a BLS-native bootloader. Probe for GRUB's own directory and let it win when both are present: grub dir + BLS entries -> Grub (Fedora/RHEL legacy BIOS, blscfg) grub dir, no BLS -> Grub (classic GRUB, unchanged) BLS entries, no grub -> Systemd (Pi 5 direct-kernel, U-Boot, coreboot) neither -> Grub (unchanged fallback) `/boot/grub2` is the Fedora/RHEL path and `/boot/grub` the Debian/Ubuntu one; both are checked. The probes still only run in the non-EFI branch, so EFI systems are unaffected and pay no extra `stat(2)`. Note the deliberate trade-off: a system migrated from GRUB to a BLS-native bootloader that left an empty `/boot/grub` behind now classifies as GRUB. That is strictly closer to correct than the behaviour on main, which returns `Bootloader::Grub` for every non-EFI system regardless, and a leftover GRUB directory is reasonable evidence that GRUB was installed. Probing for `grub.cfg` specifically would be narrower, at the cost of missing a GRUB install whose config has not been generated yet. Extends the table-driven test from 7 cases to 12, covering both new branches, the both-present disambiguation, and two regression guards: that a BLS layout with no GRUB directory is still detected as BLS (the Pi 5 case this PR exists to fix), and that UEFI classification ignores both filesystem probes entirely. Verified the new cases are not vacuous by temporarily disabling the grub-dir branch: `classify_bootloader_cases` then fails with `left: Systemd, right: Grub` on the both-present case. Full `bootc-lib` unit suite passes (233 tests), `cargo fmt --check` is clean, and clippy reports no findings in the changed regions. Assisted-by: Claude (Opus 5) Signed-off-by: Dustin Kirkland <dustin.kirkland@chainguard.dev>
Addresses review feedback on bootc-dev#2376: a legacy BIOS system that has a BLS entries directory would be classified as `Bootloader::Systemd` even though GRUB may still own the boot flow. That is a real configuration, not a hypothetical one. GRUB reads Type 1 entries itself via the `blscfg` module, and Fedora and RHEL enable that by default with `GRUB_ENABLE_BLSCFG=true`. So a legacy-BIOS Fedora or RHEL install has BOTH `/boot/grub2/` and `/boot/loader/entries/`, and the BLS probe alone cannot tell it apart from a BLS-native bootloader. Probe for GRUB's own directory and let it win when both are present: grub dir + BLS entries -> Grub (Fedora/RHEL legacy BIOS, blscfg) grub dir, no BLS -> Grub (classic GRUB, unchanged) BLS entries, no grub -> Systemd (Pi 5 direct-kernel, U-Boot, coreboot) neither -> Grub (unchanged fallback) `/boot/grub2` is the Fedora/RHEL path and `/boot/grub` the Debian/Ubuntu one; both are checked. The probes still only run in the non-EFI branch, so EFI systems are unaffected and pay no extra `stat(2)`. Note the deliberate trade-off: a system migrated from GRUB to a BLS-native bootloader that left an empty `/boot/grub` behind now classifies as GRUB. That is strictly closer to correct than the behaviour on main, which returns `Bootloader::Grub` for every non-EFI system regardless, and a leftover GRUB directory is reasonable evidence that GRUB was installed. Probing for `grub.cfg` specifically would be narrower, at the cost of missing a GRUB install whose config has not been generated yet. Extends the table-driven test from 7 cases to 12, covering both new branches, the both-present disambiguation, and two regression guards: that a BLS layout with no GRUB directory is still detected as BLS (the Pi 5 case this PR exists to fix), and that UEFI classification ignores both filesystem probes entirely. Verified the new cases are not vacuous by temporarily disabling the grub-dir branch: `classify_bootloader_cases` then fails with `left: Systemd, right: Grub` on the both-present case. Full `bootc-lib` unit suite passes (233 tests), `cargo fmt --check` is clean, and clippy reports no findings in the changed regions. Assisted-by: Claude (Opus 5) Signed-off-by: Dustin Kirkland <dustin.kirkland@chainguard.dev>
|
Rebased onto latest main. CI is now green — thanks for fixing that! I think this addresses the feedback so far: the top commit (c3671e0c) adds the /boot/grub2 + /boot/grub disambiguation @bshephar and @Johan-Liebert1 raised, so GRUB wins when both it and BLS entries are present. Would love a review when you get a chance — thanks! |
Sorry, something went wrong.
There was a problem hiding this comment.
Sorry for the delayed review. A few more changes required imo
Sorry, something went wrong.
|
Thanks @Johan-Liebert1 — (1) and (2) were straightforward:
(3) is the interesting one. Erroring instead of defaulting is a small change, bootc_composefs::status::tests::test_list_type1_entries_includes_staged bootc_composefs::gc::tests::test_boot_artifact_info_drives_migration_decisions bootc_composefs::gc::tests::test_gc_deep_transitive_sharing_chain bootc_composefs::gc::tests::test_gc_post_migration_upgrade_cycle bootc_composefs::gc::tests::test_gc_shared_boot_binaries_not_deleted bootc_composefs::gc::tests::test_gc_works_after_legacy_migration bootc_composefs::gc::tests::test_list_type1_entries_handles_legacy_bls all with: Error: Getting bootloader Caused by: Unable to determine bootloader: no EFI variables, no GRUB directory (/boot/grub2, /boot/grub), and no BLS entries at /boot/loader/entries They build a tempdir of BLS entries and call list_type1_entries, which What I have locally: list_type1_entries takes the bootloader as a parameter, One thing that fell out: in list_bootloader_entries the bootloader was being That does mean touching gc.rs (test call sites only) and changing a |
Sorry, something went wrong.
There was a problem hiding this comment.
We can, for now, unconditionally return Grub as the "default" bootloader, I guess as we only allow installing particular bootloaders anyway
Sorry, something went wrong.
There was a problem hiding this comment.
Ugh, the wall of AI text made me think comments were resolved
Sorry, something went wrong.
|
No, sorry, I was looking for guidance and explaining the implications of
your third review comment, which would involve a significant change in
behavior, and updates to at least 7 different tests.
I'll fix and resolve comments 1 and 2. But I won't address the 3rd, unless
you really want to bundle that larger change in behavior with this one...
…On Mon, Aug 24, 2026, 21:13 Pragyan Poudyal ***@***.***> wrote:
***@***.**** requested changes on this pull request.
Ugh, the wall of AI text made me think comments were resolved
—
Reply to this email directly, view it on GitHub
<#2376?email_source=notifications&email_token=AAGMZBWAFV3Y3T6JUZLV2CL5LUG5FA5CNFSNUABKM5UWIORPF5TWS5BNNB2WEL2QOVWGYUTFOF2WK43UKJSXM2LFO4XTKMBRGQ4DOMBRHAYKM4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KYZTPN52GK4S7MNWGSY3L#pullrequestreview-5014870180>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAGMZBQETTXZMN7J7G4QCQD5LUG5FAVCNFSNUABFKJSXA33TNF2G64TZHM2TOMRWHA2TSNJYHNEXG43VMU5TKMJQGU2TEMJVGE4KC5QC>
.
Triage notifications, keep track of coding agent tasks and review pull
requests on the go with GitHub Mobile for iOS
<https://github.com/notifications/mobile/ios/AAGMZBVQMCCLSXBDDA5G6VL5LUG5FA5CNFSNUABKM5UWIORPF5TWS5BNNB2WEL2QOVWGYUTFOF2WK43UKJSXM2LFO4XTKMBRGQ4DOMBRHAYKM4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KUZTPN52GK4S7NFXXG>
and Android
<https://github.com/notifications/mobile/android/AAGMZBSA62435BPFOG4JQDL5LUG5FA5CNFSNUABKM5UWIORPF5TWS5BNNB2WEL2QOVWGYUTFOF2WK43UKJSXM2LFO4XTKMBRGQ4DOMBRHAYKM4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2K4ZTPN52GK4S7MFXGI4TPNFSA>.
Download it today!
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Sorry, something went wrong.
Addresses review feedback on bootc-dev#2376: a legacy BIOS system that has a BLS entries directory would be classified as `Bootloader::Systemd` even though GRUB may still own the boot flow. That is a real configuration, not a hypothetical one. GRUB reads Type 1 entries itself via the `blscfg` module, and Fedora and RHEL enable that by default with `GRUB_ENABLE_BLSCFG=true`. So a legacy-BIOS Fedora or RHEL install has BOTH `/boot/grub2/` and `/boot/loader/entries/`, and the BLS probe alone cannot tell it apart from a BLS-native bootloader. Probe for GRUB's own directory and let it win when both are present: grub dir + BLS entries -> Grub (Fedora/RHEL legacy BIOS, blscfg) grub dir, no BLS -> Grub (classic GRUB, unchanged) BLS entries, no grub -> Systemd (Pi 5 direct-kernel, U-Boot, coreboot) neither -> Grub (unchanged fallback) `/boot/grub2` is the Fedora/RHEL path and `/boot/grub` the Debian/Ubuntu one; both are checked. The probes still only run in the non-EFI branch, so EFI systems are unaffected and pay no extra `stat(2)`. Note the deliberate trade-off: a system migrated from GRUB to a BLS-native bootloader that left an empty `/boot/grub` behind now classifies as GRUB. That is strictly closer to correct than the behaviour on main, which returns `Bootloader::Grub` for every non-EFI system regardless, and a leftover GRUB directory is reasonable evidence that GRUB was installed. Probing for `grub.cfg` specifically would be narrower, at the cost of missing a GRUB install whose config has not been generated yet. Extends the table-driven test from 7 cases to 12, covering both new branches, the both-present disambiguation, and two regression guards: that a BLS layout with no GRUB directory is still detected as BLS (the Pi 5 case this PR exists to fix), and that UEFI classification ignores both filesystem probes entirely. Verified the new cases are not vacuous by temporarily disabling the grub-dir branch: `classify_bootloader_cases` then fails with `left: Systemd, right: Grub` on the both-present case. Full `bootc-lib` unit suite passes (233 tests), `cargo fmt --check` is clean, and clippy reports no findings in the changed regions. Assisted-by: Claude (Opus 5) Signed-off-by: Dustin Kirkland <dustin.kirkland@chainguard.dev>
Two follow-ups from review on bootc-dev#2376: Reword the `BLS_ENTRIES_DIR` doc comment. It claimed the directory's presence signals a non-EFI system using the BLS layout, which is misleading: EFI systems have the directory too, and GRUB reads the same Type 1 entries via `blscfg`. It only carries information in the non-EFI branch, and only alongside the `GRUB_DIRS` probe. Cache the bootloader unconditionally. The previous `if non_efi` gate was added on the mistaken belief that unified caching broke the grub-cc tests; those failures were pre-existing and tracked separately in bootc-dev#2378. The bootloader cannot change over the lifetime of a single bootc invocation, so there is no reason to re-read `EFI_LOADER_INFO` per call. Signed-off-by: Dustin Kirkland <dustin.kirkland@chainguard.dev>
|
@Johan-Liebert1 — here's roughly what erroring instead of defaulting to GRUB would take: dustinkirkland#1 Draft in my fork for now. The two bail!s are trivial; the cost is that removing the default breaks 7 existing tests that rely on it, so list_type1_entries has to take the bootloader as a parameter instead of resolving it from ambient /boot state — which also touches gc.rs. Full suite green at +99/-51 on top of this branch. Happy to send it as a real PR if you'd like it. But it's well outside the scope of the bug I was originally fixing here, so my preference would be to keep them separate. |
Sorry, something went wrong.
`get_bootloader()` unconditionally returns `Bootloader::Grub` when
there are no EFI variables to inspect (`SystemNotUEFI` /
`MissingVar`). That's wrong for many non-EFI setups that use the Boot
Loader Specification Type 1 entry layout at `/boot/loader/entries/`
without any EFI vars to advertise it — Raspberry Pi 4/5 with direct-
kernel boot from Pi firmware, U-Boot with the extlinux/BLS loader,
coreboot chaining to a bare kernel, and various ARM/embedded boards.
When bootc misclassifies these as `Bootloader::Grub` →
`BootloaderKind::GRUBClassic`, `storage::new` sets `boot_dir =
physical_root.open_dir("boot")` = `/sysroot/boot/`. On systems where
`/boot` is a separate partition (the ESP mounted at `/boot` via the
`systemd.mount-extra=UUID=<ESP>:/boot:auto:ro` cmdline that `bootc
install to-filesystem` itself writes), `/sysroot/boot/` is empty.
Every subsequent code path that reads BLS entries via
`boot_dir.read_dir("loader/entries")` then `ENOENT`s — including the
idempotent `prepend_custom_prefix()` backwards-compat migration
called from `storage::new` itself, which is why `bootc status`,
`bootc upgrade`, and `bootc switch` all fail at storage init.
This bug was masked before bootc-dev#2356 by an EBUSY on the pre-mounted ESP.
With that fixed, execution now reaches `prepend_custom_prefix`, which
is where the wrong `boot_dir` gets used.
Fix: when there are no EFI vars, stat `/boot/loader/entries`. If it
is a directory, treat the bootloader as BLS-compatible; otherwise
fall back to `Bootloader::Grub` as before. The probe is a single
`stat(2)` and the else-branch preserves prior behaviour on real
grub-classic systems (where `/boot/grub2/` exists but
`/boot/loader/entries/` does not).
Split the inner match into a pure `classify_bootloader(efi_result,
bls_present) -> Result<Bootloader>` helper per REVIEW_RUST.md
"separate parsing from I/O" guidance, and add a table-driven unit
test covering both prior branches and both new branches.
Preserve the pre-existing "don't cache on EFI" behavior of
`get_bootloader()`: the old code had an early-return in the
`Ok(loader)` branch that bypassed the `OnceLock` cache, and the
grub-cc TMT plans observed bootloader-info changes over a run
(discovered via `is_composefs` → `bootc status --json` in
`tap.nu` after v1 of this PR unified the caching path). The new
code caches only when the classification came from the FS probe
(non-EFI, filesystem-stable state).
Verified on aarch64 with `bootc` built from this branch: before the
fix, `bootc status` errored at "Prepending custom prefix to EFI and
BLS entries: Getting sorted Type1 boot entries: No such file or
directory (os error 2)"; after, it returns a healthy `BootcHost`
report with `bootType: Bls`, and `bootc switch --transport=registry`
proceeds normally.
Assisted-by: Claude (Opus 4)
Signed-off-by: Dustin Kirkland <dustin.kirkland@chainguard.dev>
Closes: bootc-dev#2375
Addresses review feedback on bootc-dev#2376: a legacy BIOS system that has a BLS entries directory would be classified as `Bootloader::Systemd` even though GRUB may still own the boot flow. That is a real configuration, not a hypothetical one. GRUB reads Type 1 entries itself via the `blscfg` module, and Fedora and RHEL enable that by default with `GRUB_ENABLE_BLSCFG=true`. So a legacy-BIOS Fedora or RHEL install has BOTH `/boot/grub2/` and `/boot/loader/entries/`, and the BLS probe alone cannot tell it apart from a BLS-native bootloader. Probe for GRUB's own directory and let it win when both are present: grub dir + BLS entries -> Grub (Fedora/RHEL legacy BIOS, blscfg) grub dir, no BLS -> Grub (classic GRUB, unchanged) BLS entries, no grub -> Systemd (Pi 5 direct-kernel, U-Boot, coreboot) neither -> Grub (unchanged fallback) `/boot/grub2` is the Fedora/RHEL path and `/boot/grub` the Debian/Ubuntu one; both are checked. The probes still only run in the non-EFI branch, so EFI systems are unaffected and pay no extra `stat(2)`. Note the deliberate trade-off: a system migrated from GRUB to a BLS-native bootloader that left an empty `/boot/grub` behind now classifies as GRUB. That is strictly closer to correct than the behaviour on main, which returns `Bootloader::Grub` for every non-EFI system regardless, and a leftover GRUB directory is reasonable evidence that GRUB was installed. Probing for `grub.cfg` specifically would be narrower, at the cost of missing a GRUB install whose config has not been generated yet. Extends the table-driven test from 7 cases to 12, covering both new branches, the both-present disambiguation, and two regression guards: that a BLS layout with no GRUB directory is still detected as BLS (the Pi 5 case this PR exists to fix), and that UEFI classification ignores both filesystem probes entirely. Verified the new cases are not vacuous by temporarily disabling the grub-dir branch: `classify_bootloader_cases` then fails with `left: Systemd, right: Grub` on the both-present case. Full `bootc-lib` unit suite passes (233 tests), `cargo fmt --check` is clean, and clippy reports no findings in the changed regions. Assisted-by: Claude (Opus 5) Signed-off-by: Dustin Kirkland <dustin.kirkland@chainguard.dev>
Two follow-ups from review on bootc-dev#2376: Reword the `BLS_ENTRIES_DIR` doc comment. It claimed the directory's presence signals a non-EFI system using the BLS layout, which is misleading: EFI systems have the directory too, and GRUB reads the same Type 1 entries via `blscfg`. It only carries information in the non-EFI branch, and only alongside the `GRUB_DIRS` probe. Cache the bootloader unconditionally. The previous `if non_efi` gate was added on the mistaken belief that unified caching broke the grub-cc tests; those failures were pre-existing and tracked separately in bootc-dev#2378. The bootloader cannot change over the lifetime of a single bootc invocation, so there is no reason to re-read `EFI_LOADER_INFO` per call. Signed-off-by: Dustin Kirkland <dustin.kirkland@chainguard.dev>
|
Thanks for the approval review, @Johan-Liebert1. Is there anything more I need to do, to get the final checks to run and pass? The CICD testing here has stumped me over and over, these last few weeks! |
Sorry, something went wrong.
|
Looks like CI is just stuck, I will try to apply the blunt hammer approach and see if it figures things out |
Sorry, something went wrong.
|
Woohoo, it's green again! Thanks, @jeckersb ! |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Fixes #2375.
get_bootloader() unconditionally returns Bootloader::Grub when there
are no EFI variables to inspect. That's wrong for many non-EFI setups
that use the BLS Type 1 entry layout at /boot/loader/entries/
regardless — Raspberry Pi 4/5 with direct-kernel boot from Pi firmware,
U-Boot with the extlinux/BLS loader, coreboot chaining to a bare kernel,
various ARM/embedded boards.
When bootc misclassifies these as GRUBClassic, storage::new sets
boot_dir = /sysroot/boot/, which is empty on systems where /boot is
a separate ESP mounted at /boot — exactly what bootc install to-filesystem writes. Every BLS-reading code path then ENOENTs,
including the idempotent prepend_custom_prefix() migration in
storage::new itself, so bootc status, bootc upgrade, and
bootc switch all fail at storage init on affected systems.
Fix: when there are no EFI vars, stat /boot/loader/entries/. If it
is a directory, treat the bootloader as BLS-compatible; otherwise fall
back to Bootloader::Grub as before. The else-branch preserves prior
behaviour on real grub-classic systems.
Structure: split the inner match into a pure
classify_bootloader(efi_result, bls_present) -> Result<Bootloader>
helper per REVIEW_RUST.md "separate parsing from I/O" guidance. Added a
table-driven unit test with 7 cases covering both prior branches
(systemd-boot, GRUB CC, generic GRUB via EFI_LOADER_INFO) and all four
combinations of {SystemNotUEFI, MissingVar} × {BLS present, BLS absent}, plus a propagation test for other EfiError variants.
Verification: aarch64 Raspberry Pi 5, bootc 1.16.7, composefs
install with BLS layout on FAT ESP, direct-kernel boot from Pi firmware
(no UEFI at runtime).
Before:
After:
$ sudo bootc status apiVersion: org.containers.bootc/v1 kind: BootcHost ... status: booted: ... composefs: verity: <sha> bootType: Bls ← new detection path fired correctlybootc switch --transport=registry <target> also proceeds normally on
the same system after this change.
History note
This bug was masked before #2356 by an EBUSY on the pre-mounted ESP.
With that fixed, execution now reaches prepend_custom_prefix(), which
is where the wrong boot_dir gets used.
Assisted-by: Claude (Opus 4)
I authored issue #2375, directed the design (classify-vs-io split,
table-driven test coverage), and did the live before/after verification
on a real aarch64 bootc-composefs host. I have prior bootc contributions
(#2356) but am not a Rust regular — happy to iterate on style/naming.