22//
33// SPDX-License-Identifier: MPL-2.0
44
5- use std:: {
6- fmt, fs, io,
7- path:: { Path , PathBuf } ,
8- } ;
9-
10- use partition:: Partition ;
5+ mod disk;
6+ use std:: { fs, io, path:: PathBuf } ;
117
8+ pub use disk:: * ;
129pub mod nvme;
1310pub mod partition;
1411pub mod scsi;
@@ -25,151 +22,6 @@ pub enum BlockDevice {
2522 Unknown ,
2623}
2724
28- /// Represents the type of disk device.
29- #[ derive( Debug ) ]
30- pub enum Disk {
31- /// SCSI disk device (e.g. sda, sdb)
32- Scsi ( scsi:: Disk ) ,
33- /// NVMe disk device (e.g. nvme0n1)
34- Nvme ( nvme:: Disk ) ,
35- }
36-
37- /// A basic disk representation containing common attributes shared by all disk types.
38- /// This serves as the base structure that specific disk implementations build upon.
39- #[ derive( Debug ) ]
40- pub struct BasicDisk {
41- /// Device name (e.g. sda, nvme0n1)
42- pub name : String ,
43- /// Total number of sectors on the disk
44- pub sectors : u64 ,
45- /// Path to the device in sysfs
46- pub node : PathBuf ,
47- /// Path to the device in /dev
48- pub device : PathBuf ,
49- /// Optional disk model name
50- pub model : Option < String > ,
51- /// Optional disk vendor name
52- pub vendor : Option < String > ,
53- /// Partitions
54- pub partitions : Vec < Partition > ,
55- }
56-
57- impl fmt:: Display for Disk {
58- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
59- let bytes = self . size ( ) ;
60- let gib = bytes as f64 / 1_073_741_824.0 ;
61-
62- write ! ( f, "{} ({:.2} GiB)" , self . name( ) , gib) ?;
63-
64- if let Some ( vendor) = self . vendor ( ) {
65- write ! ( f, " - {}" , vendor) ?;
66- }
67-
68- if let Some ( model) = self . model ( ) {
69- write ! ( f, " {}" , model) ?;
70- }
71-
72- Ok ( ( ) )
73- }
74- }
75-
76- impl Disk {
77- /// Returns the name of the disk device.
78- pub fn name ( & self ) -> & str {
79- match self {
80- Disk :: Scsi ( disk) => & disk. name ,
81- Disk :: Nvme ( disk) => & disk. name ,
82- }
83- }
84-
85- /// Returns the partitions on the disk.
86- pub fn partitions ( & self ) -> & [ Partition ] {
87- match self {
88- Disk :: Scsi ( disk) => & disk. partitions ,
89- Disk :: Nvme ( disk) => & disk. partitions ,
90- }
91- }
92-
93- /// Returns the path to the disk device in dev.
94- pub fn device_path ( & self ) -> & Path {
95- match self {
96- Disk :: Scsi ( disk) => & disk. device ,
97- Disk :: Nvme ( disk) => & disk. device ,
98- }
99- }
100-
101- /// Returns the total number of sectors on the disk.
102- pub fn sectors ( & self ) -> u64 {
103- match self {
104- Disk :: Scsi ( disk) => disk. sectors ,
105- Disk :: Nvme ( disk) => disk. sectors ,
106- }
107- }
108-
109- /// Returns the size of the disk in bytes.
110- pub fn size ( & self ) -> u64 {
111- self . sectors ( ) * 512
112- }
113-
114- /// Returns the model name of the disk.
115- pub fn model ( & self ) -> Option < & str > {
116- match self {
117- Disk :: Scsi ( disk) => disk. model . as_deref ( ) ,
118- Disk :: Nvme ( disk) => disk. model . as_deref ( ) ,
119- }
120- }
121-
122- /// Returns the vendor name of the disk.
123- pub fn vendor ( & self ) -> Option < & str > {
124- match self {
125- Disk :: Scsi ( disk) => disk. vendor . as_deref ( ) ,
126- Disk :: Nvme ( disk) => disk. vendor . as_deref ( ) ,
127- }
128- }
129- }
130-
131- /// Trait for initializing different types of disk devices from sysfs.
132- pub ( crate ) trait DiskInit : Sized {
133- /// Creates a new disk instance by reading information from the specified sysfs path.
134- ///
135- /// # Arguments
136- ///
137- /// * `root` - The root sysfs directory path
138- /// * `name` - The name of the disk device
139- ///
140- /// # Returns
141- ///
142- /// `Some(Self)` if the disk was successfully initialized, `None` otherwise
143- fn from_sysfs_path ( root : & Path , name : & str ) -> Option < Self > ;
144- }
145-
146- impl DiskInit for BasicDisk {
147- fn from_sysfs_path ( sysroot : & Path , name : & str ) -> Option < Self > {
148- let node = sysroot. join ( name) ;
149-
150- // Read the partitions of the disk if any
151- let mut partitions: Vec < _ > = fs:: read_dir ( & node)
152- . ok ( ) ?
153- . filter_map ( Result :: ok)
154- . filter_map ( |e| {
155- let name = e. file_name ( ) . to_string_lossy ( ) . to_string ( ) ;
156- Partition :: from_sysfs_path ( sysroot, & name)
157- } )
158- . collect ( ) ;
159- partitions. sort_by_key ( |p| p. number ) ;
160-
161- Some ( Self {
162- name : name. to_owned ( ) ,
163- sectors : sysfs:: sysfs_read ( sysroot, & node, "size" ) . unwrap_or ( 0 ) ,
164- device : PathBuf :: from ( DEVFS_DIR ) . join ( name) ,
165- model : sysfs:: sysfs_read ( sysroot, & node, "device/model" ) ,
166- vendor : sysfs:: sysfs_read ( sysroot, & node, "device/vendor" ) ,
167- partitions,
168- node,
169- } )
170- }
171- }
172-
17325impl BlockDevice {
17426 /// Discovers all block devices present in the system.
17527 ///
0 commit comments