Skip to content

Commit dc0ed00

Browse files
committed
install: Use Device::list_parents for parent traversal
Replace the loop over dev.parents.take() with the new Device::list_parents() API. The inverse lsblk tree is walked to the root, with multi-parent detection preserved. Once the root device is found, refresh it via lsblk to populate its actual children (partitions). Devices from the inverse tree only carry parent links, not real children, so without this the bwrap container would lack partition device bind mounts. With no remaining consumers of the parents field, remove it from the Device struct. Assisted-by: Claude Code (Opus 4) Signed-off-by: ckyrouac <ckyrouac@redhat.com>
1 parent 58a0826 commit dc0ed00

2 files changed

Lines changed: 34 additions & 23 deletions

File tree

crates/blockdev/src/blockdev.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@ pub struct Device {
4444
pub path: Option<String>,
4545
/// Partition table type (e.g., "gpt", "dos"). Only present on whole disk devices.
4646
pub pttype: Option<String>,
47-
48-
/// Parent devices. Deprecated: use [`Device::list_parents`] instead.
49-
#[serde(skip)]
50-
pub parents: Option<Vec<Device>>,
5147
}
5248

5349
impl Device {

crates/lib/src/install.rs

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2442,27 +2442,42 @@ pub(crate) async fn install_to_filesystem(
24422442
// Find the real underlying backing device for the root. This is currently just required
24432443
// for GRUB (BIOS) and in the future zipl (I think).
24442444
let device_info = {
2445-
let mut dev = bootc_blockdev::list_dev(Utf8Path::new(&inspect.source))?;
2446-
loop {
2447-
tracing::debug!("Finding parents for {}", dev.path());
2448-
let Some(parents) = dev.parents.take() else {
2449-
break;
2450-
};
2451-
let mut parents_iter = parents.into_iter();
2452-
let Some(parent) = parents_iter.next() else {
2453-
break;
2454-
};
2455-
if let Some(next) = parents_iter.next() {
2456-
anyhow::bail!(
2457-
"Found multiple parent devices {} and {}; not currently supported",
2458-
parent.path(),
2459-
next.path()
2460-
);
2445+
let dev = bootc_blockdev::list_dev(Utf8Path::new(&inspect.source))?;
2446+
// Walk the inverse tree to the root device.
2447+
// In inverse lsblk output, "children" are actually parents.
2448+
match dev.list_parents()? {
2449+
None => {
2450+
tracing::debug!("Backing device: {}", dev.path());
2451+
dev
2452+
}
2453+
Some(parents) => {
2454+
let mut current = parents;
2455+
loop {
2456+
if current.len() > 1 {
2457+
anyhow::bail!(
2458+
"Found multiple parent devices {} and {}; not currently supported",
2459+
current[0].path(),
2460+
current[1].path()
2461+
);
2462+
}
2463+
let mut parent = current.into_iter().next().unwrap();
2464+
// In inverse output, children = grandparents
2465+
match parent.children.take() {
2466+
Some(grandparents) if !grandparents.is_empty() => {
2467+
current = grandparents;
2468+
}
2469+
_ => {
2470+
tracing::debug!("Backing device: {}", parent.path());
2471+
// Re-query the root device to populate its actual
2472+
// children (partitions). The inverse tree only
2473+
// carries parent links, not real children.
2474+
parent.refresh()?;
2475+
break parent;
2476+
}
2477+
}
2478+
}
24612479
}
2462-
dev = parent;
24632480
}
2464-
tracing::debug!("Backing device: {}", dev.path());
2465-
dev
24662481
};
24672482

24682483
let rootarg = format!("root={}", root_info.mount_spec);

0 commit comments

Comments
 (0)