Skip to content

Commit e24660f

Browse files
HuijingHeicgwalters
authored andcommitted
blockdev: find esp based on MBR or GPT
See #1736 (comment) Signed-off-by: Huijing Hei <hhei@redhat.com>
1 parent 7e81f9c commit e24660f

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

crates/blockdev/src/blockdev.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ use serde::Deserialize;
1212

1313
use bootc_utils::CommandRunExt;
1414

15+
/// EFI System Partition (ESP) on MBR
16+
/// Refer to <https://en.wikipedia.org/wiki/Partition_type>
17+
pub const ESP_ID_MBR: &[u8] = &[0x06, 0xEF];
18+
19+
/// EFI System Partition (ESP) for UEFI boot on GPT
20+
pub const ESP: &str = "c12a7328-f81f-11d2-ba4b-00a0c93ec93b";
21+
1522
#[derive(Debug, Deserialize)]
1623
struct DevicesOutput {
1724
blockdevices: Vec<Device>,
@@ -176,6 +183,19 @@ impl PartitionTable {
176183
pub fn find_partition_of_bootable(&self) -> Option<&Partition> {
177184
self.partitions.iter().find(|p| p.is_bootable())
178185
}
186+
187+
/// Find the esp partition.
188+
pub fn find_partition_of_esp(&self) -> Result<Option<&Partition>> {
189+
match &self.label {
190+
PartitionType::Dos => Ok(self.partitions.iter().find(|b| {
191+
u8::from_str_radix(&b.parttype, 16)
192+
.map(|pt| ESP_ID_MBR.contains(&pt))
193+
.unwrap_or(false)
194+
})),
195+
PartitionType::Gpt => Ok(self.find_partition_of_type(ESP)),
196+
_ => Err(anyhow::anyhow!("Unsupported partition table type")),
197+
}
198+
}
179199
}
180200

181201
impl Partition {
@@ -613,10 +633,14 @@ mod test {
613633
.find_partition_of_type("00000000-0000-0000-0000-000000000000");
614634
assert!(nonexistent.is_none());
615635

636+
// Find esp partition on GPT
637+
let esp = table.partitiontable.find_partition_of_esp()?.unwrap();
638+
assert_eq!(esp.node, "/dev/loop0p1");
639+
616640
Ok(())
617641
}
618642
#[test]
619-
fn test_find_partition_of_bootable() -> Result<()> {
643+
fn test_find_partition_of_type_mbr() -> Result<()> {
620644
let fixture = indoc::indoc! { r#"
621645
{
622646
"partitiontable": {
@@ -641,7 +665,7 @@ mod test {
641665
"node": "/dev/mmcblk0p3",
642666
"start": 3125248,
643667
"size": 121610240,
644-
"type": "83"
668+
"type": "ef"
645669
}
646670
]
647671
}
@@ -656,6 +680,10 @@ mod test {
656680
.find_partition_of_bootable()
657681
.expect("bootable partition not found");
658682
assert_eq!(esp.node, "/dev/mmcblk0p1");
683+
684+
// Find esp partition on MBR
685+
let esp1 = table.partitiontable.find_partition_of_esp()?.unwrap();
686+
assert_eq!(esp1.node, "/dev/mmcblk0p1");
659687
Ok(())
660688
}
661689
}

0 commit comments

Comments
 (0)