Inspect an MBR or GPT image
[dependencies.hadris]
version = "3.0.0-rc.2"
default-features = false
features = ["std", "sync", "part"]
use hadris::part::sync::read;
use hadris::part::{PartitionKind, PartitionTable};
use hadris::storage::host::FileDevice;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut disk = FileDevice::open("disk.img")?;
let table = read(&mut disk)?;
if let PartitionTable::Gpt(gpt) = table.table() {
if let Some(copy) = gpt.damaged_copy() {
println!("the {copy:?} GPT is damaged; writing the table repairs it");
}
}
for partition in table.partitions() {
let kind = match partition.kind() {
PartitionKind::Mbr(kind) => kind.to_string(),
PartitionKind::Gpt(guid) => guid.to_string(),
_ => String::from("unknown"),
};
let name = partition.name().map(|n| n.to_string()).unwrap_or_default();
println!(
"#{}: block {} ({} blocks, {} bytes) {kind} {name}",
partition.slot(),
partition.start(),
partition.len(),
partition.size_bytes(),
);
}
Ok(())
}
The block size comes from the device. host::FileDevice queries physical
devices and defaults regular image files to 512-byte blocks. For an image
copied from a 4Kn disk, use
FileDevice::open_with_block_size(path, BlockSize::new(4096).unwrap()).
A hadris::storage::sync::StreamDevice also takes an explicit block size. GPT CRCs are always
checked; when the primary copy is damaged the table is read from the backup,
and damaged_copy says so. Slots are zero-based: MBR primary partitions use
slots 0 to 3 and logical partitions in an extended partition follow from slot 4,
so Linux numbers are one higher (slot 4 is sda5). Disk::partition(slot)
takes the same zero-based slot that Partition::slot reports, not a Linux
partition number.
Without an allocator, hadris::part::sync::scan lists the same partitions
through a callback. To open a filesystem inside one of them, see
Open FAT inside a partition.