Skip to content

Commit 3bf1acb

Browse files
system-reinstall: Propagate boot mount in container
systemd gpt-auto-generator has automount for /boot which we need to propagate inside the container for the service to mount the ESP at /boot on access Also, before remounting `/boot` as rw, check if it's readonly so we don't fail the re-mount operation Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
1 parent 20d17fc commit 3bf1acb

4 files changed

Lines changed: 34 additions & 6 deletions

File tree

crates/lib/src/bootloader.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use cap_std_ext::dirext::CapStdExtDirExt;
1010
use fn_error_context::context;
1111

1212
use bootc_mount as mount;
13+
use rustix::fs::statfs;
1314

1415
use crate::bootc_composefs::boot::{MountedImageRoot, SecurebootKeys};
1516
use crate::utils;
@@ -46,6 +47,18 @@ const BOOTCTL_RANDOM_SEED_MIN_VERSION: u32 = 257;
4647
/// in place (bootupd will overwrite them during installation).
4748
// TODO: clean all ESPs on multi-device setups
4849
pub(crate) fn mount_esp_part(root: &Dir, root_path: &Utf8Path, is_ostree: bool) -> Result<()> {
50+
// systemd-gpt-auto-generator automounts ESP at /boot
51+
let is_boot_mountpoint = root.is_mountpoint("boot")?;
52+
53+
if matches!(is_boot_mountpoint, Some(true)) {
54+
let statfs = statfs(root_path.join("boot").as_std_path())?;
55+
56+
// We probably don't need to be this thorough, but no harm done
57+
if statfs.f_type == libc::MSDOS_SUPER_MAGIC {
58+
return Ok(());
59+
}
60+
}
61+
4962
let efi_path = Utf8Path::new("boot").join(crate::bootloader::EFI_DIR);
5063
let Some(esp_fd) = root
5164
.open_dir_optional(&efi_path)

crates/lib/src/install.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2297,12 +2297,14 @@ fn remove_all_in_dir_no_xdev(d: &Dir, mount_err: bool) -> Result<()> {
22972297
if etype == FileType::dir() {
22982298
if let Some(subdir) = d.open_dir_noxdev(&name)? {
22992299
remove_all_in_dir_no_xdev(&subdir, mount_err)?;
2300-
d.remove_dir(&name)?;
2300+
d.remove_dir(&name)
2301+
.with_context(|| format!("Removing dir {name:?}"))?;
23012302
} else if mount_err {
23022303
anyhow::bail!("Found unexpected mount point {name:?}");
23032304
}
23042305
} else {
2305-
d.remove_file_optional(&name)?;
2306+
d.remove_file_optional(&name)
2307+
.with_context(|| format!("Removing {name:?}"))?;
23062308
}
23072309
}
23082310
anyhow::Ok(())

crates/lib/src/utils.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::future::Future;
22
use std::io::Write;
3-
use std::os::fd::BorrowedFd;
3+
use std::os::fd::{AsFd, BorrowedFd};
44
use std::path::{Component, Path, PathBuf};
55
use std::process::Command;
66
use std::time::Duration;
@@ -17,6 +17,7 @@ use libsystemd::logging::journal_print;
1717
use ostree::glib;
1818
use ostree_ext::container::SignatureSource;
1919
use ostree_ext::ostree;
20+
use rustix::fs::StatVfsMountFlags;
2021

2122
/// Try to look for keys injected by e.g. rpm-ostree requesting machine-local
2223
/// changes; if any are present, return `true`.
@@ -83,7 +84,16 @@ pub fn have_executable(name: &str) -> Result<bool> {
8384
/// Given a target directory, if it's a read-only mount, then remount it writable
8485
#[context("Opening {target} with writable mount")]
8586
pub(crate) fn open_dir_remount_rw(root: &Dir, target: &Utf8Path) -> Result<Dir> {
86-
if matches!(root.is_mountpoint(target), Ok(Some(true))) {
87+
let target_dir = root.open_dir(target).with_context(|| format!("Opening {target}"))?;
88+
89+
if matches!(target_dir.is_mountpoint("."), Ok(Some(true))) {
90+
let st = rustix::fs::fstatvfs(target_dir.as_fd())
91+
.with_context(|| format!("Getting filesystem info for {target}"))?;
92+
93+
if !st.f_flag.contains(StatVfsMountFlags::RDONLY) {
94+
return Ok(target_dir);
95+
};
96+
8797
tracing::debug!("Target {target} is a mountpoint, remounting rw");
8898
let st = Command::new("mount")
8999
.args(["-o", "remount,rw", target.as_str()])
@@ -92,7 +102,8 @@ pub(crate) fn open_dir_remount_rw(root: &Dir, target: &Utf8Path) -> Result<Dir>
92102

93103
anyhow::ensure!(st.success(), "Failed to remount: {st:?}");
94104
}
95-
root.open_dir(target).map_err(anyhow::Error::new)
105+
106+
Ok(target_dir)
96107
}
97108

98109
/// Given a target path, remove its immutability if present

crates/system-reinstall-bootc/src/podman.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ pub(crate) fn reinstall_command(
5050
"--security-opt",
5151
"label=type:unconfined_t",
5252
"-v",
53-
"/:/target",
53+
// systemd gpt-auto-generator has boot.mount autofs mounted on /boot
54+
// We want to propage that inside the container
55+
"/:/target:rslave",
5456
]
5557
.map(String::from)
5658
.to_vec();

0 commit comments

Comments
 (0)