Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions crates/blockdev/src/blockdev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ use serde::Deserialize;

use bootc_utils::CommandRunExt;

/// EFI System Partition (ESP) on MBR
/// Refer to <https://en.wikipedia.org/wiki/Partition_type>
pub const ESP_ID_MBR: &[u8] = &[0x06, 0xEF];

/// EFI System Partition (ESP) for UEFI boot on GPT
pub const ESP: &str = "c12a7328-f81f-11d2-ba4b-00a0c93ec93b";

#[derive(Debug, Deserialize)]
struct DevicesOutput {
blockdevices: Vec<Device>,
Expand Down Expand Up @@ -175,6 +182,19 @@ impl PartitionTable {
pub fn find_partition_of_bootable(&self) -> Option<&Partition> {
self.partitions.iter().find(|p| p.is_bootable())
}

/// Find the esp partition.
pub fn find_partition_of_esp(&self) -> Result<Option<&Partition>> {
match &self.label {
PartitionType::Dos => Ok(self.partitions.iter().find(|b| {
u8::from_str_radix(&b.parttype, 16)
.map(|pt| ESP_ID_MBR.contains(&pt))
.unwrap_or(false)
})),
PartitionType::Gpt => Ok(self.find_partition_of_type(ESP)),
_ => Err(anyhow::anyhow!("Unsupported partition table type")),
}
}
}

impl Partition {
Expand Down Expand Up @@ -612,10 +632,14 @@ mod test {
.find_partition_of_type("00000000-0000-0000-0000-000000000000");
assert!(nonexistent.is_none());

// Find esp partition on GPT
let esp = table.partitiontable.find_partition_of_esp()?.unwrap();
assert_eq!(esp.node, "/dev/loop0p1");

Ok(())
}
#[test]
fn test_find_partition_of_bootable() -> Result<()> {
fn test_find_partition_of_type_mbr() -> Result<()> {
let fixture = indoc::indoc! { r#"
{
"partitiontable": {
Expand All @@ -640,7 +664,7 @@ mod test {
"node": "/dev/mmcblk0p3",
"start": 3125248,
"size": 121610240,
"type": "83"
"type": "ef"
}
]
}
Expand All @@ -655,6 +679,10 @@ mod test {
.find_partition_of_bootable()
.expect("bootable partition not found");
assert_eq!(esp.node, "/dev/mmcblk0p1");

// Find esp partition on MBR
let esp1 = table.partitiontable.find_partition_of_esp()?.unwrap();
assert_eq!(esp1.node, "/dev/mmcblk0p1");
Ok(())
}
}