Current Behavior
Running atomic-rollback check as a non-root user on a default Fedora install
exits 1 and reports "System has boot problems.", even when the system is fully
bootable. The underlying cause is that the check cannot read
/boot/efi/EFI/fedora/grub.cfg, which is mounted root-readable only:
$ atomic-rollback check
atomic-rollback: checking system bootability
Cannot determine how GRUB boots this system: cannot read ESP grub.cfg:
Permission denied (os error 13). Ensure /boot/efi/EFI/fedora/grub.cfg
exists and the root filesystem is mounted.
System has boot problems.
$ echo $?
1
Expected Behavior
A user running check without sufficient privilege to read the boot
configuration should be told the check could not be performed because of
insufficient access. That outcome is different from a result indicating the
system actually has boot problems. The two carry very different implications.
One means the user should re-run with appropriate privilege. The other means
the system may not boot.
Context
The current headline conclusion contradicts the detail line directly above it.
The detail correctly identifies a permission error, but the conclusion treats
it as a discovered boot problem. A user who trusts the tool's headline will
believe the system is unbootable when it is in fact fine, and may take
corrective action that itself risks the boot state.
The ESP mount is structurally root-readable-only on default Fedora installs
(fmask=0077,dmask=0077 in the live mount, mode 700 on /boot/efi), so any
non-root invocation of check reaches this path on every default install.
This is a result-classification issue, not a check-correctness issue. The
underlying check is operating as intended. The problem is that the code
flattens a "could not determine" outcome into a "found a problem" outcome.
Discovered on atomic-rollback-0.3.7-1.fc43 installed from the COPR.
Technical Details
Reproduction
On a default Fedora install with the ESP mounted at /boot/efi, as a
non-root user:
Observe exit code 1 and the conflated "System has boot problems" message.
Relevant Code
In src/main.rs:144-156, the Command::Check handler treats every
BootStatus::Fail the same way:
println!("atomic-rollback: checking system bootability\n");
match check::verify_bootable(Path::new(&root)) {
check::BootStatus::Pass => { println!("\nSystem is bootable."); }
check::BootStatus::Warn => { ... }
check::BootStatus::Fail(failures) => {
for f in &failures { eprintln!(" {f}"); }
println!("\nSystem has boot problems.");
std::process::exit(1);
}
}
In src/check.rs:51-58, verify_bootable collapses any
GrubContext::from_system error into BootStatus::Fail:
pub fn verify_bootable(root: &Path) -> BootStatus {
let grub = match GrubContext::from_system(root) {
Ok(g) => g,
Err(e) => return BootStatus::Fail(vec![format!(
"Cannot determine how GRUB boots this system: {e}. \
Ensure {}/grub.cfg exists and the root filesystem is mounted.",
P.esp_dir
)]),
};
...
}
In src/grub.rs:28-31, the io::Error from the failed read is converted to
String, which discards the ErrorKind:
let esp_cfg = root.join(&P.esp_dir[1..]).join("grub.cfg");
let content = fs::read_to_string(&esp_cfg)
.map_err(|e| format!("cannot read ESP grub.cfg: {e}"))?;
Root Cause
GrubContext::from_system returns Result<_, String>, which discards the
io::ErrorKind of the underlying read failure at the point of conversion.
Downstream code in verify_bootable and main has no way to distinguish "I
could not read the configuration" from "I read the configuration and it
indicates a problem". Both flow through the same BootStatus::Fail branch and
produce the same headline message.
Current Behavior
Running
atomic-rollback checkas a non-root user on a default Fedora installexits 1 and reports "System has boot problems.", even when the system is fully
bootable. The underlying cause is that the check cannot read
/boot/efi/EFI/fedora/grub.cfg, which is mounted root-readable only:Expected Behavior
A user running
checkwithout sufficient privilege to read the bootconfiguration should be told the check could not be performed because of
insufficient access. That outcome is different from a result indicating the
system actually has boot problems. The two carry very different implications.
One means the user should re-run with appropriate privilege. The other means
the system may not boot.
Context
The current headline conclusion contradicts the detail line directly above it.
The detail correctly identifies a permission error, but the conclusion treats
it as a discovered boot problem. A user who trusts the tool's headline will
believe the system is unbootable when it is in fact fine, and may take
corrective action that itself risks the boot state.
The ESP mount is structurally root-readable-only on default Fedora installs
(
fmask=0077,dmask=0077in the live mount, mode 700 on/boot/efi), so anynon-root invocation of
checkreaches this path on every default install.This is a result-classification issue, not a check-correctness issue. The
underlying check is operating as intended. The problem is that the code
flattens a "could not determine" outcome into a "found a problem" outcome.
Discovered on
atomic-rollback-0.3.7-1.fc43installed from the COPR.Technical Details
Reproduction
On a default Fedora install with the ESP mounted at
/boot/efi, as anon-root user:
Observe exit code 1 and the conflated "System has boot problems" message.
Relevant Code
In
src/main.rs:144-156, theCommand::Checkhandler treats everyBootStatus::Failthe same way:In
src/check.rs:51-58,verify_bootablecollapses anyGrubContext::from_systemerror intoBootStatus::Fail:In
src/grub.rs:28-31, theio::Errorfrom the failed read is converted toString, which discards theErrorKind:Root Cause
GrubContext::from_systemreturnsResult<_, String>, which discards theio::ErrorKindof the underlying read failure at the point of conversion.Downstream code in
verify_bootableandmainhas no way to distinguish "Icould not read the configuration" from "I read the configuration and it
indicates a problem". Both flow through the same
BootStatus::Failbranch andproduce the same headline message.