Skip to content

Commit bae675d

Browse files
committed
install: Allow permissive ESP detection for existing root
The strict ESP mount enforcement previously introduced caused regressions in scenarios, specifically in CI environments running inside containers (tmt/podman). In these contexts, bind mounts often mask `/boot/efi`, causing `is_mountpoint` checks to fail even when the configuration is valid. This patch introduces a `require_esp_mount` field to `RootSetup`. When targeting an existing root (host), we now utilize a permissive mode: if the explicit mount check fails, logic falls back to scanning the partition table. This restores compatibility with containerized installs while maintaining strict safety checks for `to-filesystem` and `to-disk` modes. Signed-off-by: Daniele Guarascio <guarascio.daniele@gmail.com>
1 parent 4ed589c commit bae675d

File tree

4 files changed

+44
-9
lines changed

4 files changed

+44
-9
lines changed

crates/lib/src/bootc_composefs/boot.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,20 @@ pub(crate) fn setup_composefs_bls_boot(
531531

532532
// Locate ESP partition device
533533
let esp_root = open_target_root(root_setup)?;
534-
let esp_part = crate::bootloader::require_boot_efi_mount(&esp_root)?;
534+
let esp_part = if root_setup.require_esp_mount {
535+
crate::bootloader::require_boot_efi_mount(&esp_root)?
536+
} else {
537+
match crate::bootloader::require_boot_efi_mount(&esp_root) {
538+
Ok(p) => p,
539+
Err(e) => {
540+
tracing::debug!(
541+
"ESP mount check failed in permissive mode: {e}; falling back to partition table scan"
542+
);
543+
let esp = crate::bootloader::esp_in(&root_setup.device_info)?;
544+
esp.node.clone()
545+
}
546+
}
547+
};
535548

536549
(
537550
root_setup.physical_root_path.clone(),
@@ -1074,7 +1087,21 @@ pub(crate) fn setup_composefs_uki_boot(
10741087
state.require_no_kargs_for_uki()?;
10751088

10761089
let esp_root = open_target_root(root_setup)?;
1077-
let esp_part = crate::bootloader::require_boot_efi_mount(&esp_root)?;
1090+
1091+
let esp_part = if root_setup.require_esp_mount {
1092+
crate::bootloader::require_boot_efi_mount(&esp_root)?
1093+
} else {
1094+
match crate::bootloader::require_boot_efi_mount(&esp_root) {
1095+
Ok(p) => p,
1096+
Err(e) => {
1097+
tracing::debug!(
1098+
"ESP mount check failed in permissive mode: {e}; falling back to partition table scan"
1099+
);
1100+
let esp = crate::bootloader::esp_in(&root_setup.device_info)?;
1101+
esp.node.clone()
1102+
}
1103+
}
1104+
};
10781105

10791106
(
10801107
root_setup.physical_root_path.clone(),
@@ -1254,6 +1281,7 @@ pub(crate) async fn setup_composefs_boot(
12541281
&root_setup.physical_root_path,
12551282
&state.config_opts,
12561283
None,
1284+
root_setup.require_esp_mount,
12571285
)?;
12581286
} else {
12591287
crate::bootloader::install_systemd_boot(

crates/lib/src/bootloader.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,14 @@ pub(crate) fn install_via_bootupd(
9292
rootfs: &Utf8Path,
9393
configopts: &crate::install::InstallConfigOpts,
9494
deployment_path: Option<&str>,
95+
require_mount: bool,
9596
) -> Result<()> {
96-
// We require /boot/efi to be mounted; finding the device is just a sanity check that it is.
97-
// The device argument is currently used by bootupctl as a fallback if it can't find the ESP.
98-
// But we want to fail fast if our own check fails.
99-
let _esp_device = require_boot_efi_mount(root)?;
97+
if require_mount {
98+
// We require /boot/efi to be mounted; finding the device is just a sanity check that it is.
99+
// The device argument is currently used by bootupctl as a fallback if it can't find the ESP.
100+
// But we want to fail fast if our own check fails.
101+
let _esp_device = require_boot_efi_mount(root)?;
102+
}
100103

101104
let verbose = std::env::var_os("BOOTC_BOOTLOADER_DEBUG").map(|_| "-vvvv");
102105
// bootc defaults to only targeting the platform boot method.

crates/lib/src/install.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,6 +1160,7 @@ pub(crate) struct RootSetup {
11601160
skip_finalize: bool,
11611161
boot: Option<MountSpec>,
11621162
pub(crate) kargs: CmdlineOwned,
1163+
pub(crate) require_esp_mount: bool,
11631164
}
11641165

11651166
fn require_boot_uuid(spec: &MountSpec) -> Result<&str> {
@@ -1625,6 +1626,7 @@ async fn install_with_sysroot(
16251626
&target_root_path,
16261627
&state.config_opts,
16271628
Some(&deployment_path.as_str()),
1629+
rootfs.require_esp_mount,
16281630
)?;
16291631
}
16301632
Bootloader::Systemd => {
@@ -2012,11 +2014,11 @@ fn remove_all_except_loader_dirs(bootdir: &Dir, is_ostree: bool) -> Result<()> {
20122014
}
20132015

20142016
#[context("Removing boot directory content")]
2015-
fn clean_boot_directories(rootfs: &Dir, is_ostree: bool) -> Result<()> {
2017+
fn clean_boot_directories(rootfs: &Dir, is_ostree: bool, strict_esp: bool) -> Result<()> {
20162018
let bootdir =
20172019
crate::utils::open_dir_remount_rw(rootfs, BOOT.into()).context("Opening /boot")?;
20182020

2019-
if ARCH_USES_EFI {
2021+
if ARCH_USES_EFI && strict_esp {
20202022
// Require an explicit /boot/efi mount to avoid cleaning the wrong ESP.
20212023
crate::bootloader::require_boot_efi_mount(rootfs)?;
20222024
}
@@ -2232,7 +2234,7 @@ pub(crate) async fn install_to_filesystem(
22322234
.await??;
22332235
}
22342236
Some(ReplaceMode::Alongside) => {
2235-
clean_boot_directories(&target_rootfs_fd, is_already_ostree)?
2237+
clean_boot_directories(&target_rootfs_fd, is_already_ostree, !targeting_host_root)?
22362238
}
22372239
None => require_empty_rootdir(&rootfs_fd)?,
22382240
}
@@ -2394,6 +2396,7 @@ pub(crate) async fn install_to_filesystem(
23942396
boot,
23952397
kargs,
23962398
skip_finalize,
2399+
require_esp_mount: !targeting_host_root,
23972400
};
23982401

23992402
install_to_filesystem_impl(&state, &mut rootfs, cleanup).await?;

crates/lib/src/install/baseline.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,5 +496,6 @@ pub(crate) fn install_create_rootfs(
496496
boot,
497497
kargs,
498498
skip_finalize: false,
499+
require_esp_mount: true,
499500
})
500501
}

0 commit comments

Comments
 (0)