@@ -51,6 +51,39 @@ impl Device {
51
51
pub ( crate ) fn has_children ( & self ) -> bool {
52
52
self . children . as_ref ( ) . map_or ( false , |v| !v. is_empty ( ) )
53
53
}
54
+
55
+ // The "start" parameter was only added in a version of util-linux that's only
56
+ // in Fedora 40 as of this writing.
57
+ fn backfill_start ( & mut self ) -> Result < ( ) > {
58
+ let Some ( majmin) = self . maj_min . as_deref ( ) else {
59
+ // This shouldn't happen
60
+ return Ok ( ( ) ) ;
61
+ } ;
62
+ let sysfs_start_path = format ! ( "/sys/dev/block/{majmin}/start" ) ;
63
+ if Utf8Path :: new ( & sysfs_start_path) . try_exists ( ) ? {
64
+ let start = std:: fs:: read_to_string ( & sysfs_start_path)
65
+ . with_context ( || format ! ( "Reading {sysfs_start_path}" ) ) ?;
66
+ tracing:: debug!( "backfilled start to {start}" ) ;
67
+ self . start = Some (
68
+ start
69
+ . trim ( )
70
+ . parse ( )
71
+ . context ( "Parsing sysfs start property" ) ?,
72
+ ) ;
73
+ }
74
+ Ok ( ( ) )
75
+ }
76
+
77
+ /// Older versions of util-linux may be missing some properties. Backfill them if they're missing.
78
+ pub ( crate ) fn backfill_missing ( & mut self ) -> Result < ( ) > {
79
+ // Add new properties to backfill here
80
+ self . backfill_start ( ) ?;
81
+ // And recurse to child devices
82
+ for child in self . children . iter_mut ( ) . flatten ( ) {
83
+ child. backfill_missing ( ) ?;
84
+ }
85
+ Ok ( ( ) )
86
+ }
54
87
}
55
88
56
89
#[ context( "Failed to wipe {dev}" ) ]
@@ -70,7 +103,10 @@ fn list_impl(dev: Option<&Utf8Path>) -> Result<Vec<Device>> {
70
103
if !o. status . success ( ) {
71
104
return Err ( anyhow:: anyhow!( "Failed to list block devices" ) ) ;
72
105
}
73
- let devs: DevicesOutput = serde_json:: from_reader ( & * o. stdout ) ?;
106
+ let mut devs: DevicesOutput = serde_json:: from_reader ( & * o. stdout ) ?;
107
+ for dev in devs. blockdevices . iter_mut ( ) {
108
+ dev. backfill_missing ( ) ?;
109
+ }
74
110
Ok ( devs. blockdevices )
75
111
}
76
112
0 commit comments