Skip to content

Commit

Permalink
Skip efi if no ESP device detected and skip bios if no bios_boot found
Browse files Browse the repository at this point in the history
  • Loading branch information
HuijingHei committed Sep 20, 2024
1 parent 870332c commit 53c2dbc
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 15 deletions.
49 changes: 47 additions & 2 deletions src/bios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,29 @@ use std::path::Path;
use std::process::Command;

use crate::component::*;
use crate::efi;
use crate::model::*;
use crate::packagesystem;
use anyhow::{bail, Result};

use crate::util;
use serde::{Deserialize, Serialize};

// grub2-install file path
pub(crate) const GRUB_BIN: &str = "usr/sbin/grub2-install";

#[derive(Serialize, Deserialize, Debug)]
struct BlockDevice {
path: String,
pttype: String,
parttypename: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
struct Devices {
blockdevices: Vec<BlockDevice>,
}

#[derive(Default)]
pub(crate) struct Bios {}

Expand All @@ -22,12 +36,11 @@ impl Bios {
#[cfg(target_arch = "x86_64")]
{
// find /boot partition
let boot_dir = Path::new("/").join("boot");
cmd = Command::new("findmnt");
cmd.arg("--noheadings")
.arg("--output")
.arg("SOURCE")
.arg(boot_dir);
.arg("/boot");
let partition = util::cmd_output(&mut cmd)?;

// lsblk to find parent device
Expand Down Expand Up @@ -81,6 +94,34 @@ impl Bios {
}
Ok(())
}

// check bios_boot partition on gpt type disk
fn get_bios_boot_partition(&self) -> Result<Option<String>> {
let target = self.get_device()?;
// lsblk to list children with bios_boot
let output = Command::new("lsblk")
.args(["--json", "--output", "PATH,PTTYPE,PARTTYPENAME", target.trim()])
.output()?;
if !output.status.success() {
std::io::stderr().write_all(&output.stderr)?;
bail!("Failed to run lsblk");
}

let output = String::from_utf8(output.stdout)?;
// Parse the JSON string into the `Devices` struct
let devices: Devices = serde_json::from_str(&output).expect("JSON was not well-formatted");

// Find the device with the parttypename "BIOS boot"
for device in devices.blockdevices {
if let Some(parttypename) = &device.parttypename {
if parttypename == "BIOS boot" && device.pttype == "gpt" {
return Ok(Some(device.path))
}
}
}
Ok(None)
}

}

impl Component for Bios {
Expand Down Expand Up @@ -122,6 +163,10 @@ impl Component for Bios {
}

fn query_adopt(&self) -> Result<Option<Adoptable>> {
if efi::is_efi_booted()? && self.get_bios_boot_partition()?.is_none() {
log::debug!("Skip BIOS adopt");
return Ok(None);
}
crate::component::query_adopt_state()
}

Expand Down
2 changes: 1 addition & 1 deletion src/bootupd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ pub(crate) fn print_status(status: &Status) -> Result<()> {

#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
{
let boot_method = if Path::new("/sys/firmware/efi").exists() {
let boot_method = if efi::is_efi_booted()? {
"EFI"
} else {
"BIOS"
Expand Down
35 changes: 23 additions & 12 deletions src/efi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ impl Efi {
}

fn open_esp_optional(&self) -> Result<Option<openat::Dir>> {
if !is_efi_booted()? && self.get_esp_device().is_none() {
log::debug!("Skip EFI");
return Ok(None);
}
let sysroot = openat::Dir::open("/")?;
let esp = sysroot.sub_dir_optional(&self.esp_path()?)?;
Ok(esp)
Expand All @@ -75,6 +79,20 @@ impl Efi {
Ok(esp)
}

fn get_esp_device(&self) -> Option<PathBuf> {
let esp_devices = [COREOS_ESP_PART_LABEL, ANACONDA_ESP_PART_LABEL]
.into_iter()
.map(|p| Path::new("/dev/disk/by-partlabel/").join(p));
let mut esp_device = None;
for path in esp_devices {
if path.exists() {
esp_device = Some(path);
break;
}
}
return esp_device;
}

pub(crate) fn ensure_mounted_esp(&self, root: &Path) -> Result<PathBuf> {
let mut mountpoint = self.mountpoint.borrow_mut();
if let Some(mountpoint) = mountpoint.as_deref() {
Expand All @@ -93,18 +111,8 @@ impl Efi {
log::debug!("Reusing existing {mnt:?}");
return Ok(mnt);
}

let esp_devices = [COREOS_ESP_PART_LABEL, ANACONDA_ESP_PART_LABEL]
.into_iter()
.map(|p| Path::new("/dev/disk/by-partlabel/").join(p));
let mut esp_device = None;
for path in esp_devices {
if path.exists() {
esp_device = Some(path);
break;
}
}
let esp_device = esp_device.ok_or_else(|| anyhow::anyhow!("Failed to find ESP device"))?;

let esp_device = self.get_esp_device().ok_or_else(|| anyhow::anyhow!("Failed to find ESP device"))?;
for &mnt in ESP_MOUNTS.iter() {
let mnt = root.join(mnt);
if !mnt.exists() {
Expand Down Expand Up @@ -388,6 +396,9 @@ impl Component for Efi {
}

fn validate(&self, current: &InstalledContent) -> Result<ValidationResult> {
if !is_efi_booted()? && self.get_esp_device().is_none() {
return Ok(ValidationResult::Skip);
}
let currentf = current
.filetree
.as_ref()
Expand Down

0 comments on commit 53c2dbc

Please sign in to comment.