Skip to content

Commit 60298f5

Browse files
committed
Add support for minor nodes, extend deviceslots example
1 parent 9281773 commit 60298f5

File tree

4 files changed

+395
-23
lines changed

4 files changed

+395
-23
lines changed

Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ edition = "2021"
77
anyhow = "1.0.62"
88
libc = "0.2.132"
99
num_enum = "0.5.7"
10+
11+
[dev-dependencies]
12+
clap = { version = "4.1.1", features = [ "derive" ] }

examples/deviceslots.rs

+51-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
use anyhow::Result;
1+
use anyhow::{anyhow, Result};
2+
use clap::{Parser, ValueEnum};
23
use illumos_devinfo::*;
34
use std::collections::BTreeMap;
5+
use std::path::PathBuf;
46

57
fn slot_to_device(slot: i64) -> Option<&'static str> {
68
match slot {
@@ -22,7 +24,42 @@ fn slot_to_device(slot: i64) -> Option<&'static str> {
2224
}
2325
}
2426

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+
2560
fn main() -> Result<()> {
61+
let args = Args::parse();
62+
2663
let mut device_info = DevInfo::new()?;
2764
let mut node_walker = device_info.walk_node();
2865

@@ -31,8 +68,9 @@ fn main() -> Result<()> {
3168
while let Some(mut node) = node_walker.next().transpose()? {
3269
if let Some(driver_name) = node.driver_name() {
3370
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() {
3674
node = parent;
3775
if let Some(Ok(slot_prop)) = node.props().into_iter().find(|prop| {
3876
if let Ok(prop) = prop {
@@ -44,16 +82,23 @@ fn main() -> Result<()> {
4482
let slot = slot_prop.as_i64().expect("Expected i64");
4583
let device = slot_to_device(slot).unwrap_or("Not found");
4684

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+
);
4994
break;
5095
}
5196
}
5297
}
5398
}
5499
}
55100

56-
println!("Slot\tDevice\tDevfs Path");
101+
println!("Slot\tDevice\tPath");
57102
for device in device_descriptions.values() {
58103
println!("{device}");
59104
}

examples/disks.rs

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use anyhow::Result;
2+
use illumos_devinfo::*;
3+
4+
fn main() -> Result<()> {
5+
let mut di = DevInfo::new()?;
6+
7+
let mut w = di.walk_node();
8+
while let Some(n) = w.next().transpose()? {
9+
let mut wm = n.minors();
10+
while let Some(m) = wm.next().transpose()? {
11+
/*
12+
* Disks will either have the DDI_NT_BLOCK node type, or one of the
13+
* more specific DDI_NT_BLOCK* subtypes (with a suffix after the
14+
* colon):
15+
*/
16+
if m.node_type() != "ddi_block" && !m.node_type().starts_with("ddi_block:") {
17+
continue;
18+
}
19+
20+
/*
21+
* Just look for raw (not block) disk devices.
22+
*/
23+
if m.spec_type() != SpecType::Char {
24+
continue;
25+
}
26+
27+
println!("{}: {}", m.node_type(), m.devfs_path()?);
28+
29+
let links = DevLinks::new(false)?;
30+
for l in links.links_for_path(m.devfs_path()?)? {
31+
println!(" {:?}", l.path());
32+
}
33+
}
34+
}
35+
36+
Ok(())
37+
}

0 commit comments

Comments
 (0)