Skip to content

Commit de4dafb

Browse files
authored
Merge pull request bootc-dev#729 from HuijingHei/skip-check-component
Skip `UEFI` or `BIOS` on none hybrid partition layout
2 parents 0d62c43 + b1ca767 commit de4dafb

File tree

3 files changed

+76
-18
lines changed

3 files changed

+76
-18
lines changed

src/bios.rs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,23 @@ use crate::packagesystem;
88
use anyhow::{bail, Result};
99

1010
use crate::util;
11+
use serde::{Deserialize, Serialize};
1112

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

16+
#[derive(Serialize, Deserialize, Debug)]
17+
struct BlockDevice {
18+
path: String,
19+
pttype: String,
20+
parttypename: Option<String>,
21+
}
22+
23+
#[derive(Serialize, Deserialize, Debug)]
24+
struct Devices {
25+
blockdevices: Vec<BlockDevice>,
26+
}
27+
1528
#[derive(Default)]
1629
pub(crate) struct Bios {}
1730

@@ -22,12 +35,11 @@ impl Bios {
2235
#[cfg(target_arch = "x86_64")]
2336
{
2437
// find /boot partition
25-
let boot_dir = Path::new("/").join("boot");
2638
cmd = Command::new("findmnt");
2739
cmd.arg("--noheadings")
2840
.arg("--output")
2941
.arg("SOURCE")
30-
.arg(boot_dir);
42+
.arg("/boot");
3143
let partition = util::cmd_output(&mut cmd)?;
3244

3345
// lsblk to find parent device
@@ -81,6 +93,38 @@ impl Bios {
8193
}
8294
Ok(())
8395
}
96+
97+
// check bios_boot partition on gpt type disk
98+
fn get_bios_boot_partition(&self) -> Result<Option<String>> {
99+
let target = self.get_device()?;
100+
// lsblk to list children with bios_boot
101+
let output = Command::new("lsblk")
102+
.args([
103+
"--json",
104+
"--output",
105+
"PATH,PTTYPE,PARTTYPENAME",
106+
target.trim(),
107+
])
108+
.output()?;
109+
if !output.status.success() {
110+
std::io::stderr().write_all(&output.stderr)?;
111+
bail!("Failed to run lsblk");
112+
}
113+
114+
let output = String::from_utf8(output.stdout)?;
115+
// Parse the JSON string into the `Devices` struct
116+
let devices: Devices = serde_json::from_str(&output).expect("JSON was not well-formatted");
117+
118+
// Find the device with the parttypename "BIOS boot"
119+
for device in devices.blockdevices {
120+
if let Some(parttypename) = &device.parttypename {
121+
if parttypename == "BIOS boot" && device.pttype == "gpt" {
122+
return Ok(Some(device.path));
123+
}
124+
}
125+
}
126+
Ok(None)
127+
}
84128
}
85129

86130
impl Component for Bios {
@@ -120,6 +164,11 @@ impl Component for Bios {
120164
}
121165

122166
fn query_adopt(&self) -> Result<Option<Adoptable>> {
167+
#[cfg(target_arch = "x86_64")]
168+
if crate::efi::is_efi_booted()? && self.get_bios_boot_partition()?.is_none() {
169+
log::debug!("Skip BIOS adopt");
170+
return Ok(None);
171+
}
123172
crate::component::query_adopt_state()
124173
}
125174

src/bootupd.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -380,11 +380,7 @@ pub(crate) fn print_status(status: &Status) -> Result<()> {
380380

381381
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
382382
{
383-
let boot_method = if Path::new("/sys/firmware/efi").exists() {
384-
"EFI"
385-
} else {
386-
"BIOS"
387-
};
383+
let boot_method = if efi::is_efi_booted()? { "EFI" } else { "BIOS" };
388384
println!("Boot method: {}", boot_method);
389385
}
390386

src/efi.rs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ impl Efi {
6363
}
6464

6565
fn open_esp_optional(&self) -> Result<Option<openat::Dir>> {
66+
if !is_efi_booted()? && self.get_esp_device().is_none() {
67+
log::debug!("Skip EFI");
68+
return Ok(None);
69+
}
6670
let sysroot = openat::Dir::open("/")?;
6771
let esp = sysroot.sub_dir_optional(&self.esp_path()?)?;
6872
Ok(esp)
@@ -75,6 +79,20 @@ impl Efi {
7579
Ok(esp)
7680
}
7781

82+
fn get_esp_device(&self) -> Option<PathBuf> {
83+
let esp_devices = [COREOS_ESP_PART_LABEL, ANACONDA_ESP_PART_LABEL]
84+
.into_iter()
85+
.map(|p| Path::new("/dev/disk/by-partlabel/").join(p));
86+
let mut esp_device = None;
87+
for path in esp_devices {
88+
if path.exists() {
89+
esp_device = Some(path);
90+
break;
91+
}
92+
}
93+
return esp_device;
94+
}
95+
7896
pub(crate) fn ensure_mounted_esp(&self, root: &Path) -> Result<PathBuf> {
7997
let mut mountpoint = self.mountpoint.borrow_mut();
8098
if let Some(mountpoint) = mountpoint.as_deref() {
@@ -94,17 +112,9 @@ impl Efi {
94112
return Ok(mnt);
95113
}
96114

97-
let esp_devices = [COREOS_ESP_PART_LABEL, ANACONDA_ESP_PART_LABEL]
98-
.into_iter()
99-
.map(|p| Path::new("/dev/disk/by-partlabel/").join(p));
100-
let mut esp_device = None;
101-
for path in esp_devices {
102-
if path.exists() {
103-
esp_device = Some(path);
104-
break;
105-
}
106-
}
107-
let esp_device = esp_device.ok_or_else(|| anyhow::anyhow!("Failed to find ESP device"))?;
115+
let esp_device = self
116+
.get_esp_device()
117+
.ok_or_else(|| anyhow::anyhow!("Failed to find ESP device"))?;
108118
for &mnt in ESP_MOUNTS.iter() {
109119
let mnt = root.join(mnt);
110120
if !mnt.exists() {
@@ -386,6 +396,9 @@ impl Component for Efi {
386396
}
387397

388398
fn validate(&self, current: &InstalledContent) -> Result<ValidationResult> {
399+
if !is_efi_booted()? && self.get_esp_device().is_none() {
400+
return Ok(ValidationResult::Skip);
401+
}
389402
let currentf = current
390403
.filetree
391404
.as_ref()

0 commit comments

Comments
 (0)