1
- use anyhow:: Result ;
1
+ use anyhow:: { anyhow, Result } ;
2
+ use clap:: { Parser , ValueEnum } ;
2
3
use illumos_devinfo:: * ;
3
4
use std:: collections:: BTreeMap ;
5
+ use std:: path:: PathBuf ;
4
6
5
7
fn slot_to_device ( slot : i64 ) -> Option < & ' static str > {
6
8
match slot {
@@ -22,7 +24,42 @@ fn slot_to_device(slot: i64) -> Option<&'static str> {
22
24
}
23
25
}
24
26
27
+ fn get_whole_disk_dev_link ( node : & Node < ' _ > ) -> Result < PathBuf > {
28
+ // Each of the letter-indexed references into block device
29
+ // slices are represented as minor nodes.
30
+ let mut wm = node. minors ( ) ;
31
+ while let Some ( m) = wm. next ( ) . transpose ( ) ? {
32
+ // Find the minor of the "whole disk"
33
+ if m. name ( ) == "wd" {
34
+ let links = DevLinks :: new ( false ) ?;
35
+ for l in links. links_for_path ( m. devfs_path ( ) ?) ? {
36
+ return Ok ( l. path ( ) . to_path_buf ( ) ) ;
37
+ }
38
+ }
39
+ }
40
+ Err ( anyhow ! ( "No whole disk minor found" ) )
41
+ }
42
+
43
+ #[ derive( Copy , Clone , PartialEq , Eq , Debug , ValueEnum ) ]
44
+ enum PathFlavor {
45
+ /// Emit the path within "/devices"
46
+ Devfs ,
47
+ /// Emit the path within "/dev"
48
+ Dev ,
49
+ }
50
+
51
+ /// Progam to identify disks, their types, and their paths.
52
+ #[ derive( Parser , Debug ) ]
53
+ #[ command( author, version, about, long_about = None ) ]
54
+ struct Args {
55
+ /// The type of path to emit
56
+ #[ arg( short, long, value_enum, default_value_t = PathFlavor :: Devfs ) ]
57
+ flavor : PathFlavor ,
58
+ }
59
+
25
60
fn main ( ) -> Result < ( ) > {
61
+ let args = Args :: parse ( ) ;
62
+
26
63
let mut device_info = DevInfo :: new ( ) ?;
27
64
let mut node_walker = device_info. walk_node ( ) ;
28
65
@@ -31,8 +68,9 @@ fn main() -> Result<()> {
31
68
while let Some ( mut node) = node_walker. next ( ) . transpose ( ) ? {
32
69
if let Some ( driver_name) = node. driver_name ( ) {
33
70
if driver_name == "blkdev" {
34
- let devfs_path = node. devfs_path ( ) ?;
35
- while let Some ( parent) = node. parent ( ) {
71
+ let dev_path = get_whole_disk_dev_link ( & node) ?;
72
+ let devfs_path = PathBuf :: from ( format ! ( "/devices{}" , node. devfs_path( ) ?) ) ;
73
+ while let Ok ( Some ( parent) ) = node. parent ( ) {
36
74
node = parent;
37
75
if let Some ( Ok ( slot_prop) ) = node. props ( ) . into_iter ( ) . find ( |prop| {
38
76
if let Ok ( prop) = prop {
@@ -44,16 +82,23 @@ fn main() -> Result<()> {
44
82
let slot = slot_prop. as_i64 ( ) . expect ( "Expected i64" ) ;
45
83
let device = slot_to_device ( slot) . unwrap_or ( "Not found" ) ;
46
84
47
- device_descriptions
48
- . insert ( slot, format ! ( "{slot:>4}\t {device:>6}\t {devfs_path}" ) ) ;
85
+ let path = match args. flavor {
86
+ PathFlavor :: Devfs => devfs_path,
87
+ PathFlavor :: Dev => dev_path,
88
+ } ;
89
+
90
+ device_descriptions. insert (
91
+ slot,
92
+ format ! ( "{slot:>4}\t {device:>6}\t {path}" , path = path. display( ) ) ,
93
+ ) ;
49
94
break ;
50
95
}
51
96
}
52
97
}
53
98
}
54
99
}
55
100
56
- println ! ( "Slot\t Device\t Devfs Path " ) ;
101
+ println ! ( "Slot\t Device\t Path " ) ;
57
102
for device in device_descriptions. values ( ) {
58
103
println ! ( "{device}" ) ;
59
104
}
0 commit comments