@@ -292,7 +292,7 @@ impl Device {
292292 /// Returns the root device with its children (partitions) populated.
293293 /// If this device is already a root device, returns a clone of `self`.
294294 /// Fails if the device has multiple parents at any level.
295- pub fn root_disk ( & self ) -> Result < Device > {
295+ pub fn find_single_root ( & self ) -> Result < Device > {
296296 let Some ( parents) = self . list_parents ( ) ? else {
297297 // Already a root device; re-query to ensure children are populated
298298 return list_dev ( Utf8Path :: new ( & self . path ( ) ) ) ;
@@ -316,6 +316,34 @@ impl Device {
316316 }
317317 }
318318 }
319+
320+ /// Walk the parent chain to find all root (whole disk) devices.
321+ ///
322+ /// Returns all root devices with their children (partitions) populated.
323+ /// Unlike find_single_root, this handles devices backed by multiple
324+ /// parents (e.g. RAID arrays) by following all branches of the parent tree.
325+ /// If this device is already a root device, returns a single-element list.
326+ pub fn find_all_roots ( & self ) -> Result < Vec < Device > > {
327+ let Some ( parents) = self . list_parents ( ) ? else {
328+ // Already a root device; re-query to ensure children are populated
329+ return Ok ( vec ! [ list_dev( Utf8Path :: new( & self . path( ) ) ) ?] ) ;
330+ } ;
331+
332+ let mut roots = Vec :: new ( ) ;
333+ let mut queue = parents;
334+ while let Some ( mut device) = queue. pop ( ) {
335+ match device. children . take ( ) {
336+ Some ( grandparents) if !grandparents. is_empty ( ) => {
337+ queue. extend ( grandparents) ;
338+ }
339+ _ => {
340+ // Found a root; re-query to populate its actual children
341+ roots. push ( list_dev ( Utf8Path :: new ( & device. path ( ) ) ) ?) ;
342+ }
343+ }
344+ }
345+ Ok ( roots)
346+ }
319347}
320348
321349#[ context( "Listing device {dev}" ) ]
0 commit comments