Skip to content

Commit a04ec67

Browse files
committed
install: mount esp part before clean_boot_directories()
On ostree OS like FCOS, esp is not mounted after booted, need to find esp and mount before clean, or `/boot/efi` will be removed. Signed-off-by: Huijing Hei <hhei@redhat.com>
1 parent 87ccef4 commit a04ec67

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

crates/lib/src/bootloader.rs

Lines changed: 32 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,36 @@ 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+
if let Some(esp) = esp {
40+
return Ok(Some(esp.node.clone()));
41+
};
42+
Ok(None)
43+
}
44+
45+
// Mount esp part at /boot/efi
46+
pub(crate) fn mount_esp_part(root: &Dir, root_path: &Utf8Path, physical_root: &Dir) -> Result<()> {
47+
let efi_path = Utf8Path::new("boot").join(crate::bootloader::EFI_DIR);
48+
if let Some(esp_fd) = root
49+
.open_dir_optional(&efi_path)
50+
.context("Opening /boot/efi")?
51+
{
52+
if let Some(false) = esp_fd.is_mountpoint(".")? {
53+
tracing::debug!("Not a mountpoint: /boot/efi");
54+
// On ostree env, should use /target/sysroot because of composefs
55+
if let Some(esp_part) = get_esp_partition_node(&physical_root)? {
56+
bootc_mount::mount(&esp_part, &root_path.join(&efi_path))?;
57+
tracing::debug!("Mounted {esp_part} at /boot/efi");
58+
}
59+
}
60+
}
61+
Ok(())
62+
}
63+
3364
/// Determine if the invoking environment contains bootupd, and if there are bootupd-based
3465
/// updates in the target root.
3566
#[context("Querying for bootupd")]

crates/lib/src/install.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,6 +2196,15 @@ pub(crate) async fn install_to_filesystem(
21962196
.await??;
21972197
}
21982198
Some(ReplaceMode::Alongside) => {
2199+
// On existing ostree OS like FCOS, esp is not mounted after booted,
2200+
// need to find esp and mount before clean
2201+
if ARCH_USES_EFI {
2202+
crate::bootloader::mount_esp_part(
2203+
&target_rootfs_fd,
2204+
&target_root_path,
2205+
&rootfs_fd,
2206+
)?;
2207+
}
21992208
clean_boot_directories(&target_rootfs_fd, is_already_ostree)?
22002209
}
22012210
None => require_empty_rootdir(&rootfs_fd)?,

0 commit comments

Comments
 (0)