Skip to content

Commit

Permalink
lib/bootloader: Write to PReP partition on ppc64le
Browse files Browse the repository at this point in the history
    Bootloader code currently writes required data to base/parent
    device (eg /dev/sda). This logic does not work for ppc64le
    architecture as bootloader configuration has to be written
    to PRePboot partition(typically first partition of disk).

    This patch adds code to identify PowerPC-PReP-boot partition
    (for ppc64le architecture) and writes bootloader data to it.
    realpath command is used to identify PReP partition.

    Incase of writing to qcow2 image, first partition of loopback
    device is used as it points to PRePBoot. In order to identify
    loopback device usage the patch introduces a boolean flag to
    filesystem_impl() routine.

Signed-off-by: Sachin Sant <sachinp@linux.ibm.com>
  • Loading branch information
sacsant committed Jul 4, 2024
1 parent 94521ec commit bd66f53
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 5 deletions.
35 changes: 34 additions & 1 deletion lib/src/bootloader.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
use std::process::Command;
use std::str;

use anyhow::Context;
use anyhow::Result;
use camino::Utf8Path;
use fn_error_context::context;
Expand All @@ -12,15 +16,44 @@ pub(crate) fn install_via_bootupd(
device: &Utf8Path,
rootfs: &Utf8Path,
configopts: &crate::install::InstallConfigOpts,
via_loopback: bool,
) -> Result<()> {
let device_str: &str;
let prepboot_dir;
let verbose = std::env::var_os("BOOTC_BOOTLOADER_DEBUG").map(|_| "-vvvv");
// bootc defaults to only targeting the platform boot method.
let bootupd_opts = (!configopts.generic_image).then_some(["--update-firmware", "--auto"]);

if cfg!(target_arch = "powerpc64") {
// get PowerPC-PReP-boot device information
if via_loopback {
// While writing to a qcow2 image use first partition
// of loopback device as it points to
// PowerPC-PReP-boot partition
device_str = "/dev/loop0p1";
} else {
// While writing to a disk use realpath to extract
// PowerPC-PReP-boot partition
let result = Command::new("realpath")
.arg("-L")
.arg("/dev/disk/by-partlabel/PowerPC-PReP-boot")
.output()
.with_context(|| format!("Find PowerPC-PReP-boot partition"))?;
if !result.status.success() {
println!("{}", String::from_utf8_lossy(&result.stderr));
anyhow::bail!("realpath failed with {}", result.status);
}
prepboot_dir = String::from_utf8(result.stdout).unwrap();
device_str = prepboot_dir.trim();
}
} else {
device_str = device.as_str()
}
let args = ["backend", "install", "--write-uuid"]
.into_iter()
.chain(verbose)
.chain(bootupd_opts.iter().copied().flatten())
.chain(["--device", device.as_str(), rootfs.as_str()]);
.chain(["--device", device_str, rootfs.as_str()]);
Task::new("Running bootupctl to install bootloader", "bootupctl")
.args(args)
.verbose()
Expand Down
10 changes: 6 additions & 4 deletions lib/src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1216,7 +1216,7 @@ async fn prepare_install(
Ok(state)
}

async fn install_to_filesystem_impl(state: &State, rootfs: &mut RootSetup) -> Result<()> {
async fn install_to_filesystem_impl(state: &State, rootfs: &mut RootSetup, loopback: bool) -> Result<()> {
if matches!(state.selinux_state, SELinuxFinalState::ForceTargetDisabled) {
rootfs.kargs.push("selinux=0".to_string());
}
Expand All @@ -1240,7 +1240,8 @@ async fn install_to_filesystem_impl(state: &State, rootfs: &mut RootSetup) -> Re
.context("Writing aleph version")?;
}

crate::bootloader::install_via_bootupd(&rootfs.device, &rootfs.rootfs, &state.config_opts)?;
// boolean flag to identify loopback usage
crate::bootloader::install_via_bootupd(&rootfs.device, &rootfs.rootfs, &state.config_opts, loopback)?;
tracing::debug!("Installed bootloader");

// Finalize mounted filesystems
Expand Down Expand Up @@ -1307,7 +1308,7 @@ pub(crate) async fn install_to_disk(mut opts: InstallToDiskOpts) -> Result<()> {
(rootfs, loopback_dev)
};

install_to_filesystem_impl(&state, &mut rootfs).await?;
install_to_filesystem_impl(&state, &mut rootfs, opts.via_loopback).await?;

// Drop all data about the root except the bits we need to ensure any file descriptors etc. are closed.
let (root_path, luksdev) = rootfs.into_storage();
Expand Down Expand Up @@ -1631,7 +1632,8 @@ pub(crate) async fn install_to_filesystem(
skip_finalize,
};

install_to_filesystem_impl(&state, &mut rootfs).await?;
// set loopback to true, used only with powerpc64 arch in bootloader
install_to_filesystem_impl(&state, &mut rootfs, true).await?;

// Drop all data about the root except the path to ensure any file descriptors etc. are closed.
drop(rootfs);
Expand Down

0 comments on commit bd66f53

Please sign in to comment.