Skip to content

Commit 67361c4

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 2c20ee9 commit 67361c4

4 files changed

Lines changed: 44 additions & 9 deletions

File tree

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
@@ -1298,6 +1298,7 @@ pub(crate) struct RootSetup {
12981298
skip_finalize: bool,
12991299
boot: Option<MountSpec>,
13001300
pub(crate) kargs: CmdlineOwned,
1301+
pub(crate) require_esp_mount: bool,
13011302
}
13021303

13031304
fn require_boot_uuid(spec: &MountSpec) -> Result<&str> {
@@ -1772,6 +1773,7 @@ async fn install_with_sysroot(
17721773
&target_root_path,
17731774
&state.config_opts,
17741775
Some(&deployment_path.as_str()),
1776+
rootfs.require_esp_mount,
17751777
)?;
17761778
}
17771779
Bootloader::Systemd => {
@@ -2159,11 +2161,11 @@ fn remove_all_except_loader_dirs(bootdir: &Dir, is_ostree: bool) -> Result<()> {
21592161
}
21602162

21612163
#[context("Removing boot directory content")]
2162-
fn clean_boot_directories(rootfs: &Dir, is_ostree: bool) -> Result<()> {
2164+
fn clean_boot_directories(rootfs: &Dir, is_ostree: bool, strict_esp: bool) -> Result<()> {
21632165
let bootdir =
21642166
crate::utils::open_dir_remount_rw(rootfs, BOOT.into()).context("Opening /boot")?;
21652167

2166-
if ARCH_USES_EFI {
2168+
if ARCH_USES_EFI && strict_esp {
21672169
// Require an explicit /boot/efi mount to avoid cleaning the wrong ESP.
21682170
crate::bootloader::require_boot_efi_mount(rootfs)?;
21692171
}
@@ -2379,7 +2381,7 @@ pub(crate) async fn install_to_filesystem(
23792381
.await??;
23802382
}
23812383
Some(ReplaceMode::Alongside) => {
2382-
clean_boot_directories(&target_rootfs_fd, is_already_ostree)?
2384+
clean_boot_directories(&target_rootfs_fd, is_already_ostree, !targeting_host_root)?
23832385
}
23842386
None => require_empty_rootdir(&rootfs_fd)?,
23852387
}
@@ -2541,6 +2543,7 @@ pub(crate) async fn install_to_filesystem(
25412543
boot,
25422544
kargs,
25432545
skip_finalize,
2546+
require_esp_mount: !targeting_host_root,
25442547
};
25452548

25462549
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)