Skip to content

Commit 4b9202b

Browse files
committed
blockdev: Add Device::root_disk() to find the whole-disk ancestor
Add a root_disk() method that walks the parent chain via lsblk --inverse to find the root (whole disk) device, then refreshes it to populate its actual children (partitions). This is needed by callers that start from a partition device (e.g. from list_dev_by_dir on /sysroot) and need to find sibling partitions such as the ESP. Assisted-by: Claude Code (Opus 4) Signed-off-by: ckyrouac <ckyrouac@redhat.com>
1 parent 62ea078 commit 4b9202b

1 file changed

Lines changed: 31 additions & 0 deletions

File tree

crates/blockdev/src/blockdev.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,37 @@ impl Device {
184184
}
185185
}
186186

187+
/// Walk the parent chain to find the root (whole disk) device.
188+
///
189+
/// Returns the root device with its children (partitions) populated.
190+
/// If this device is already a root device, returns a clone of `self`.
191+
/// Fails if the device has multiple parents at any level.
192+
pub fn root_disk(&self) -> Result<Device> {
193+
let Some(parents) = self.list_parents()? else {
194+
// Already a root device; re-query to ensure children are populated
195+
return list_dev(Utf8Path::new(&self.path()));
196+
};
197+
let mut current = parents;
198+
loop {
199+
anyhow::ensure!(
200+
current.len() == 1,
201+
"Device {} has multiple parents; cannot determine root disk",
202+
self.path()
203+
);
204+
let mut parent = current.into_iter().next().unwrap();
205+
match parent.children.take() {
206+
Some(grandparents) if !grandparents.is_empty() => {
207+
current = grandparents;
208+
}
209+
_ => {
210+
// Found the root; re-query to populate its actual children
211+
parent.refresh()?;
212+
return Ok(parent);
213+
}
214+
}
215+
}
216+
}
217+
187218
/// Return this device's children, querying lsblk if not already populated.
188219
///
189220
/// Devices obtained from a parent (inverse) chain lack children;

0 commit comments

Comments
 (0)