@@ -7,7 +7,10 @@ use std::{
77 path:: { Path , PathBuf } ,
88} ;
99
10+ use partition:: Partition ;
11+
1012pub mod nvme;
13+ pub mod partition;
1114pub mod scsi;
1215mod sysfs;
1316
@@ -19,6 +22,7 @@ const DEVFS_DIR: &str = "/dev";
1922pub enum BlockDevice {
2023 /// A physical disk device
2124 Disk ( Box < Disk > ) ,
25+ Unknown ,
2226}
2327
2428/// Represents the type of disk device.
@@ -46,23 +50,26 @@ pub struct BasicDisk {
4650 pub model : Option < String > ,
4751 /// Optional disk vendor name
4852 pub vendor : Option < String > ,
53+ /// Partitions
54+ pub partitions : Vec < Partition > ,
4955}
5056
5157impl Disk {
5258 /// Returns the name of the disk device.
53- ///
54- /// # Examples
55- ///
56- /// ```
57- /// // Returns strings like "sda" or "nvme0n1"
58- /// let name = disk.name();
59- /// ```
6059 pub fn name ( & self ) -> & str {
6160 match self {
6261 Disk :: Scsi ( disk) => disk. name ( ) ,
6362 Disk :: Nvme ( disk) => disk. name ( ) ,
6463 }
6564 }
65+
66+ /// Returns the partitions on the disk.
67+ pub fn partitions ( & self ) -> & [ Partition ] {
68+ match self {
69+ Disk :: Scsi ( disk) => disk. partitions ( ) ,
70+ Disk :: Nvme ( disk) => disk. partitions ( ) ,
71+ }
72+ }
6673}
6774
6875/// Trait for initializing different types of disk devices from sysfs.
@@ -83,12 +90,25 @@ pub(crate) trait DiskInit: Sized {
8390impl DiskInit for BasicDisk {
8491 fn from_sysfs_path ( sysroot : & Path , name : & str ) -> Option < Self > {
8592 let node = sysroot. join ( name) ;
93+
94+ // Read the partitions of the disk if any
95+ let mut partitions: Vec < _ > = fs:: read_dir ( & node)
96+ . ok ( ) ?
97+ . filter_map ( Result :: ok)
98+ . filter_map ( |e| {
99+ let name = e. file_name ( ) . to_string_lossy ( ) . to_string ( ) ;
100+ Partition :: from_sysfs_path ( sysroot, & name)
101+ } )
102+ . collect ( ) ;
103+ partitions. sort_by_key ( |p| p. number ) ;
104+
86105 Some ( Self {
87106 name : name. to_owned ( ) ,
88107 sectors : sysfs:: sysfs_read ( sysroot, & node, "size" ) . unwrap_or ( 0 ) ,
89108 device : PathBuf :: from ( DEVFS_DIR ) . join ( name) ,
90109 model : sysfs:: sysfs_read ( sysroot, & node, "device/model" ) ,
91110 vendor : sysfs:: sysfs_read ( sysroot, & node, "device/vendor" ) ,
111+ partitions,
92112 node,
93113 } )
94114 }
@@ -100,15 +120,6 @@ impl BlockDevice {
100120 /// # Returns
101121 ///
102122 /// A vector of discovered block devices or an IO error if the discovery fails.
103- ///
104- /// # Examples
105- ///
106- /// ```
107- /// let devices = BlockDevice::discover()?;
108- /// for device in devices {
109- /// println!("Found device: {:?}", device);
110- /// }
111- /// ```
112123 pub fn discover ( ) -> io:: Result < Vec < BlockDevice > > {
113124 Self :: discover_in_sysroot ( "/" )
114125 }
@@ -157,7 +168,13 @@ mod tests {
157168 #[ test]
158169 fn test_discover ( ) {
159170 let devices = BlockDevice :: discover ( ) . unwrap ( ) ;
160- assert ! ( !devices. is_empty( ) ) ;
161- eprintln ! ( "devices: {devices:?}" ) ;
171+ for device in & devices {
172+ if let BlockDevice :: Disk ( disk) = device {
173+ println ! ( "{}:" , disk. name( ) ) ;
174+ for partition in disk. partitions ( ) {
175+ println ! ( "├─{}" , partition. name) ;
176+ }
177+ }
178+ }
162179 }
163180}
0 commit comments