From 63af2d0b9c6c83cabb3548b841016735d5c8e2cb Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 6 Feb 2025 12:45:41 -0500 Subject: [PATCH] bios+ppc64le: Support being passed a whole device And automatically find the PReP partition. Closes: https://github.com/coreos/bootupd/issues/837 Signed-off-by: Colin Walters --- src/bios.rs | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/bios.rs b/src/bios.rs index 2e85f01c..6e528b8a 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -1,4 +1,6 @@ use anyhow::{bail, Result}; +#[cfg(target_arch = "powerpc64")] +use std::borrow::Cow; use std::io::prelude::*; use std::os::unix::io::AsRawFd; use std::path::Path; @@ -12,6 +14,30 @@ use crate::packagesystem; // grub2-install file path pub(crate) const GRUB_BIN: &str = "usr/sbin/grub2-install"; +#[cfg(target_arch = "powerpc64")] +fn target_device(device: &str) -> Result> { + const PREPBOOT_GUID: &str = "9E1A2D38-C612-4316-AA26-8B49521E5A8B"; + /// We make a best-effort to support MBR partitioning too. + const PREPBOOT_MBR_TYPE: &str = "41"; + + // Here we use lsblk to see if the device has any partitions at all + let dev = bootc_blockdev::list_dev(device.into())?; + if dev.children.is_none() { + return Ok(device.into()); + }; + // If it does, directly call `sfdisk` and bypass lsblk because inside a container + // we may not have all the cached udev state (that I think is in /run). + let device = bootc_blockdev::partitions_of(device.into())?; + let prepdev = device + .partitions + .iter() + .find(|p| matches!(p.parttype.as_str(), PREPBOOT_GUID | PREPBOOT_MBR_TYPE)) + .ok_or_else(|| { + anyhow::anyhow!("Failed to find PReP partition with GUID {PREPBOOT_GUID}") + })?; + Ok(prepdev.path().as_str().to_owned().into()) +} + #[derive(Default)] pub(crate) struct Bios {} @@ -54,10 +80,13 @@ impl Bios { .arg(device); #[cfg(target_arch = "powerpc64")] - cmd.args(&["--target", "powerpc-ieee1275"]) - .args(&["--boot-directory", boot_dir.to_str().unwrap()]) - .arg("--no-nvram") - .arg(device); + { + let device = target_device(device)?; + cmd.args(&["--target", "powerpc-ieee1275"]) + .args(&["--boot-directory", boot_dir.to_str().unwrap()]) + .arg("--no-nvram") + .arg(&*device); + } let cmdout = cmd.output()?; if !cmdout.status.success() {