From 6d2eb2aaa92e23f434c47e3d0ebadc0307d45289 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 19 Aug 2025 13:11:35 +0200 Subject: [PATCH 1/2] install: Access sysroot via /proc/$pid instead of /proc/self /proc/self doesn't resolve correctly for subprocesses that may be spawned. In particular, if ostree spawns aboot-deploy to update the aboot symlinks that will fail. --- crates/lib/src/install.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/lib/src/install.rs b/crates/lib/src/install.rs index 296b2ba4e..d9ccffbfb 100644 --- a/crates/lib/src/install.rs +++ b/crates/lib/src/install.rs @@ -19,6 +19,7 @@ use std::io::Write; use std::os::fd::{AsFd, AsRawFd}; use std::os::unix::process::CommandExt; use std::path::Path; +use std::process; use std::process::Command; use std::str::FromStr; use std::sync::Arc; @@ -624,7 +625,11 @@ async fn initialize_ostree_root(state: &State, root_setup: &RootSetup) -> Result } let sysroot = { - let path = format!("/proc/self/fd/{}", rootfs_dir.as_fd().as_raw_fd()); + let path = format!( + "/proc/{}/fd/{}", + process::id(), + rootfs_dir.as_fd().as_raw_fd() + ); ostree::Sysroot::new(Some(&gio::File::for_path(path))) }; sysroot.load(cancellable)?; From 7d276a2ad649b9e7b8b8ee602324c57f85cc4aae Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 19 Aug 2025 13:13:38 +0200 Subject: [PATCH 2/2] install: Detect aboot images and enable the correct bootloader Aboot images need to have the ostree bootloader backend set to "aboot", otherwise the deploy during bootc install will not create the correct boot A/B symlinks, and additionally once booted will not correctly deploy to the aboot partition during an update. To see whethere an image is using aboot, we look for the "aboot.img" file in the kernel modules dir. NOTE: In order to correctly handle running bootc from a different container than the to-be-installed container we look for aboot.img in the actual commit, not just in the running container. --- crates/lib/src/install.rs | 19 +++++++++++++++++++ crates/ostree-ext/src/bootabletree.rs | 15 +++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/crates/lib/src/install.rs b/crates/lib/src/install.rs index d9ccffbfb..b5cca4a6e 100644 --- a/crates/lib/src/install.rs +++ b/crates/lib/src/install.rs @@ -779,6 +779,25 @@ async fn install_container( )?; let kargsd = kargsd.iter().map(|s| s.as_str()); + // If the target uses aboot, then we need to set that bootloader in the ostree + // config before deploying the commit + if ostree_ext::bootabletree::commit_has_aboot_img(&merged_ostree_root, None)? { + tracing::debug!("Setting bootloader to aboot"); + Command::new("ostree") + .args([ + "config", + "--repo", + "ostree/repo", + "set", + "sysroot.bootloader", + "aboot", + ]) + .cwd_dir(root_setup.physical_root.try_clone()?) + .run_capture_stderr() + .context("Setting bootloader config to aboot")?; + sysroot.repo().reload_config(None::<&gio::Cancellable>)?; + } + // Keep this in sync with install/completion.rs for the Anaconda fixups let install_config_kargs = state .install_config diff --git a/crates/ostree-ext/src/bootabletree.rs b/crates/ostree-ext/src/bootabletree.rs index 23ab3b723..0b9d2c04a 100644 --- a/crates/ostree-ext/src/bootabletree.rs +++ b/crates/ostree-ext/src/bootabletree.rs @@ -12,6 +12,7 @@ use ostree::prelude::*; const MODULES: &str = "usr/lib/modules"; const VMLINUZ: &str = "vmlinuz"; +const ABOOT_IMG: &str = "aboot.img"; /// Find the kernel modules directory in a bootable OSTree commit. /// The target directory will have a `vmlinuz` file representing the kernel binary. @@ -88,6 +89,20 @@ pub fn find_kernel_dir_fs(root: &Dir) -> Result> { Ok(r) } +/// Check if there is an aboot image in the kernel tree dir +pub fn commit_has_aboot_img( + root: &gio::File, + cancellable: Option<&gio::Cancellable>, +) -> Result { + if let Some(kernel_dir) = find_kernel_dir(root, cancellable)? { + Ok(kernel_dir + .resolve_relative_path(ABOOT_IMG) + .query_exists(cancellable)) + } else { + Ok(false) + } +} + #[cfg(test)] mod test { use super::*;