Skip to content

Commit d4e52b6

Browse files
committed
install: mount esp in clean_boot_directories()
On FCOS, esp is not mounted after booted, need to find esp and mount before cleaning, or `/boot/efi` will be removed. Signed-off-by: Huijing Hei <hhei@redhat.com>
1 parent 3c93ab1 commit d4e52b6

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

crates/lib/src/bootloader.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ use anyhow::{anyhow, bail, Context, Result};
55
use bootc_utils::CommandRunExt;
66
use camino::Utf8Path;
77
use cap_std_ext::cap_std::fs::Dir;
8+
use cap_std_ext::dirext::CapStdExtDirExt;
89
use fn_error_context::context;
910

1011
use bootc_blockdev::{Partition, PartitionTable};
1112
use bootc_mount as mount;
1213

13-
use crate::bootc_composefs::boot::{mount_esp, SecurebootKeys};
14+
use crate::bootc_composefs::boot::{get_sysroot_parent_dev, mount_esp, SecurebootKeys};
1415
use crate::{discoverable_partition_specification, utils};
1516

1617
/// The name of the mountpoint for efi (as a subdirectory of /boot, or at the toplevel)
@@ -30,6 +31,42 @@ pub(crate) fn esp_in(device: &PartitionTable) -> Result<&Partition> {
3031
.ok_or(anyhow::anyhow!("ESP not found in partition table"))
3132
}
3233

34+
/// Get esp partition node based on the root dir
35+
pub(crate) fn get_esp_partition_node(root: &Dir) -> Result<Option<String>> {
36+
let device = get_sysroot_parent_dev(&root)?;
37+
let base_partitions = bootc_blockdev::partitions_of(Utf8Path::new(&device))?;
38+
let esp = base_partitions.find_partition_of_esp()?;
39+
Ok(esp.map(|v| v.node.clone()))
40+
}
41+
42+
/// Mount ESP part at /boot/efi
43+
pub(crate) fn mount_esp_part(root: &Dir, root_path: &Utf8Path, is_ostree: bool) -> Result<()> {
44+
let efi_path = Utf8Path::new("boot").join(crate::bootloader::EFI_DIR);
45+
let Some(esp_fd) = root
46+
.open_dir_optional(&efi_path)
47+
.context("Opening /boot/efi")?
48+
else {
49+
return Ok(());
50+
};
51+
52+
let Some(false) = esp_fd.is_mountpoint(".")? else {
53+
return Ok(());
54+
};
55+
56+
tracing::debug!("Not a mountpoint: /boot/efi");
57+
// On ostree env with enabled composefs, should be /target/sysroot
58+
let physical_root = if is_ostree {
59+
&root.open_dir("sysroot").context("Opening /sysroot")?
60+
} else {
61+
root
62+
};
63+
if let Some(esp_part) = get_esp_partition_node(physical_root)? {
64+
bootc_mount::mount(&esp_part, &root_path.join(&efi_path))?;
65+
tracing::debug!("Mounted {esp_part} at /boot/efi");
66+
}
67+
Ok(())
68+
}
69+
3370
/// Determine if the invoking environment contains bootupd, and if there are bootupd-based
3471
/// updates in the target root.
3572
#[context("Querying for bootupd")]

crates/lib/src/install.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,15 +1980,20 @@ fn remove_all_except_loader_dirs(bootdir: &Dir, is_ostree: bool) -> Result<()> {
19801980
}
19811981

19821982
#[context("Removing boot directory content")]
1983-
fn clean_boot_directories(rootfs: &Dir, is_ostree: bool) -> Result<()> {
1983+
fn clean_boot_directories(rootfs: &Dir, rootfs_path: &Utf8Path, is_ostree: bool) -> Result<()> {
19841984
let bootdir =
19851985
crate::utils::open_dir_remount_rw(rootfs, BOOT.into()).context("Opening /boot")?;
19861986

1987+
if ARCH_USES_EFI {
1988+
// On booted FCOS, esp is not mounted by default
1989+
// Mount ESP part at /boot/efi before clean
1990+
crate::bootloader::mount_esp_part(&rootfs, &rootfs_path, is_ostree)?;
1991+
}
1992+
19871993
// This should not remove /boot/efi note.
19881994
remove_all_except_loader_dirs(&bootdir, is_ostree).context("Emptying /boot")?;
19891995

1990-
// TODO: Discover the ESP the same way bootupd does it; we should also
1991-
// support not wiping the ESP.
1996+
// TODO: we should also support not wiping the ESP.
19921997
if ARCH_USES_EFI {
19931998
if let Some(efidir) = bootdir
19941999
.open_dir_optional(crate::bootloader::EFI_DIR)
@@ -2196,7 +2201,7 @@ pub(crate) async fn install_to_filesystem(
21962201
.await??;
21972202
}
21982203
Some(ReplaceMode::Alongside) => {
2199-
clean_boot_directories(&target_rootfs_fd, is_already_ostree)?
2204+
clean_boot_directories(&target_rootfs_fd, &target_root_path, is_already_ostree)?
22002205
}
22012206
None => require_empty_rootdir(&rootfs_fd)?,
22022207
}

0 commit comments

Comments
 (0)