From b3e35c4161c530f818f4fdda3b4620b94ebbd866 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 22 Oct 2023 13:12:59 -0400 Subject: [PATCH 1/2] install: Track `is_alongside` We're going to need to dispatch other behavior on this around the bootloader, so make it a generic thing. Signed-off-by: Colin Walters --- lib/src/install.rs | 8 ++++---- lib/src/install/baseline.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/src/install.rs b/lib/src/install.rs index 32b632a89..69349c8fb 100644 --- a/lib/src/install.rs +++ b/lib/src/install.rs @@ -632,8 +632,8 @@ pub(crate) struct RootSetup { rootfs: Utf8PathBuf, rootfs_fd: Dir, rootfs_uuid: Option, - /// If true, do not try to remount the root read-only and flush the journal, etc. - skip_finalize: bool, + /// True if this is an "alongside" install where we didn't create the filesystem + is_alongside: bool, boot: Option, kargs: Vec, } @@ -882,7 +882,7 @@ async fn install_to_filesystem_impl(state: &State, rootfs: &mut RootSetup) -> Re .run()?; // Finalize mounted filesystems - if !rootfs.skip_finalize { + if !rootfs.is_alongside { let bootfs = rootfs.rootfs.join("boot"); for fs in [bootfs.as_path(), rootfs.rootfs.as_path()] { finalize_filesystem(fs)?; @@ -1112,7 +1112,7 @@ pub(crate) async fn install_to_filesystem(opts: InstallToFilesystemOpts) -> Resu rootfs_uuid: inspect.uuid.clone(), boot, kargs, - skip_finalize: matches!(fsopts.replace, Some(ReplaceMode::Alongside)), + is_alongside: matches!(fsopts.replace, Some(ReplaceMode::Alongside)), }; install_to_filesystem_impl(&state, &mut rootfs).await?; diff --git a/lib/src/install/baseline.rs b/lib/src/install/baseline.rs index 9eeb1cd78..e6875cb3c 100644 --- a/lib/src/install/baseline.rs +++ b/lib/src/install/baseline.rs @@ -387,6 +387,6 @@ pub(crate) fn install_create_rootfs( rootfs_uuid: Some(root_uuid.to_string()), boot: Some(boot), kargs, - skip_finalize: false, + is_alongside: false, }) } From 20aa19ce6da58078999368e4f6dd948b2e3d990b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 22 Oct 2023 13:16:07 -0400 Subject: [PATCH 2/2] install/alongside: Match bootloader method by default Today Anaconda defaults to setting up the bootloader with source == target mode; on x86_64 that means if booted via BIOS the system is installed just with BIOS, and EFI if booted via EFI. Hence, we must match the target boot method only. (TODO: drive down into bootupd something like `backend install --component=auto`) Signed-off-by: Colin Walters --- lib/src/bootloader.rs | 48 +++++++++++++++++++++++++++++++++++-------- lib/src/install.rs | 7 ++++++- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/lib/src/bootloader.rs b/lib/src/bootloader.rs index 24d28eda6..39c0d1511 100644 --- a/lib/src/bootloader.rs +++ b/lib/src/bootloader.rs @@ -1,4 +1,5 @@ use std::os::unix::prelude::PermissionsExt; +use std::path::Path; use anyhow::{Context, Result}; use camino::Utf8Path; @@ -51,20 +52,51 @@ fn install_grub2_efi(efidir: &Dir, uuid: &str) -> Result<()> { Ok(()) } +/// Return `true` if the system is booted via EFI +pub(crate) fn is_efi_booted() -> Result { + if !super::install::ARCH_USES_EFI { + return Ok(false); + } + Path::new("/sys/firmware/efi") + .try_exists() + .map_err(Into::into) +} + #[context("Installing bootloader")] pub(crate) fn install_via_bootupd( device: &Utf8Path, rootfs: &Utf8Path, boot_uuid: &str, + is_alongside: bool, ) -> Result<()> { let verbose = std::env::var_os("BOOTC_BOOTLOADER_DEBUG").map(|_| "-vvvv"); - let args = ["backend", "install"].into_iter().chain(verbose).chain([ - "--src-root", - "/", - "--device", - device.as_str(), - rootfs.as_str(), - ]); + // If we're doing an alongside install, only match the boot method because Anaconda defaults + // to only doing that. This is only on x86_64 because that's the only arch that has multiple + // components right now. + // TODO: Add --component=auto which moves this logic into bootupd + let (install_efi, component_args) = if cfg!(target_arch = "x86_64") && is_alongside { + assert!(super::install::ARCH_USES_EFI); + let install_efi = is_efi_booted()?; + let component_arg = if install_efi { + "--component=EFI" + } else { + "--component=BIOS" + }; + (install_efi, Some(component_arg)) + } else { + (super::install::ARCH_USES_EFI, None) + }; + let args = ["backend", "install"] + .into_iter() + .chain(verbose) + .chain(component_args) + .chain([ + "--src-root", + "/", + "--device", + device.as_str(), + rootfs.as_str(), + ]); Task::new_and_run("Running bootupctl to install bootloader", "bootupctl", args)?; let grub2_uuid_contents = format!("set BOOT_UUID=\"{boot_uuid}\"\n"); @@ -73,7 +105,7 @@ pub(crate) fn install_via_bootupd( let bootfs = Dir::open_ambient_dir(bootfs, cap_std::ambient_authority()).context("Opening boot")?; - if super::install::ARCH_USES_EFI { + if super::install::ARCH_USES_EFI && install_efi { let efidir = bootfs.open_dir("efi").context("Opening efi")?; install_grub2_efi(&efidir, &grub2_uuid_contents)?; } diff --git a/lib/src/install.rs b/lib/src/install.rs index 69349c8fb..3d8ef2c21 100644 --- a/lib/src/install.rs +++ b/lib/src/install.rs @@ -861,7 +861,12 @@ async fn install_to_filesystem_impl(state: &State, rootfs: &mut RootSetup) -> Re .get_boot_uuid()? .or(rootfs.rootfs_uuid.as_deref()) .ok_or_else(|| anyhow!("No uuid for boot/root"))?; - crate::bootloader::install_via_bootupd(&rootfs.device, &rootfs.rootfs, boot_uuid)?; + crate::bootloader::install_via_bootupd( + &rootfs.device, + &rootfs.rootfs, + boot_uuid, + rootfs.is_alongside, + )?; tracing::debug!("Installed bootloader"); // If Ignition is specified, enable it