@@ -284,7 +284,7 @@ impl Device {
284284 /// Returns the root device with its children (partitions) populated.
285285 /// If this device is already a root device, returns a clone of `self`.
286286 /// Fails if the device has multiple parents at any level.
287- pub fn root_disk ( & self ) -> Result < Device > {
287+ pub fn find_single_root ( & self ) -> Result < Device > {
288288 let Some ( parents) = self . list_parents ( ) ? else {
289289 // Already a root device; re-query to ensure children are populated
290290 return list_dev ( Utf8Path :: new ( & self . path ( ) ) ) ;
@@ -308,6 +308,34 @@ impl Device {
308308 }
309309 }
310310 }
311+
312+ /// Walk the parent chain to find all root (whole disk) devices.
313+ ///
314+ /// Returns all root devices with their children (partitions) populated.
315+ /// Unlike find_single_root, this handles devices backed by multiple
316+ /// parents (e.g. RAID arrays) by following all branches of the parent tree.
317+ /// If this device is already a root device, returns a single-element list.
318+ pub fn find_all_roots ( & self ) -> Result < Vec < Device > > {
319+ let Some ( parents) = self . list_parents ( ) ? else {
320+ // Already a root device; re-query to ensure children are populated
321+ return Ok ( vec ! [ list_dev( Utf8Path :: new( & self . path( ) ) ) ?] ) ;
322+ } ;
323+
324+ let mut roots = Vec :: new ( ) ;
325+ let mut queue = parents;
326+ while let Some ( mut device) = queue. pop ( ) {
327+ match device. children . take ( ) {
328+ Some ( grandparents) if !grandparents. is_empty ( ) => {
329+ queue. extend ( grandparents) ;
330+ }
331+ _ => {
332+ // Found a root; re-query to populate its actual children
333+ roots. push ( list_dev ( Utf8Path :: new ( & device. path ( ) ) ) ?) ;
334+ }
335+ }
336+ }
337+ Ok ( roots)
338+ }
311339}
312340
313341#[ context( "Listing device {dev}" ) ]
0 commit comments