Skip to content

Commit

Permalink
Merge pull request #38 from navidys/class_sas_port
Browse files Browse the repository at this point in the history
added /sys/class/sas_port
  • Loading branch information
navidys authored Dec 6, 2024
2 parents 09ee920 + 39a6cd9 commit 3db73af
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 1 deletion.
6 changes: 6 additions & 0 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,12 @@ Supported Features
* phy-*
* ports-*

*`/sys/class/sas_port/<NAME>/`
* device/
* phy-*
* expander-*
* end_device-*

*`/sys/class/scsi_tape/<NAME>/statistics`
* write_ns
* read_byte_cnt
Expand Down
13 changes: 13 additions & 0 deletions examples/sas_port.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use procsys::sysfs::class_sas_port;

fn main() {
let sasports = class_sas_port::collect().expect("sas ports information");

match serde_json::to_string_pretty(&sasports) {
Ok(output) => println!("{}", output),
Err(err) => {
log::error!("{}", err);
std::process::exit(1);
}
}
}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ pub mod process_ns;
pub mod softirqs;
pub mod swaps;
pub mod sysfs;
pub mod utils;
mod utils;
123 changes: 123 additions & 0 deletions src/sysfs/class_sas_port.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
use regex::Regex;
use serde::Serialize;
use std::{collections::HashMap, path::PathBuf};

use crate::{
error::{CollectResult, MetricError},
utils,
};

#[derive(Debug, Serialize, Clone, Default)]
pub struct SASPort {
/// /sys/class/sas_device/<Name>/device/phy-*
pub sas_phys: Vec<String>,

/// /sys/class/sas_port/<Name>/device/expander-*
pub expanders: Vec<String>,

/// /sys/class/sas_port/<Name>/device/end_device-*
pub end_devices: Vec<String>,
}

impl SASPort {
fn new() -> Self {
Default::default()
}
}

/// collects sas ports information
/// # Example
/// ```
/// use procsys::sysfs::class_sas_port;
///
/// let sasports = class_sas_port::collect().expect("sas ports information");
/// let json_output = serde_json::to_string_pretty(&sasports).unwrap();
/// println!("{}", json_output);
///
/// ```
pub fn collect() -> CollectResult<HashMap<String, SASPort>> {
collect_from("/sys/class/sas_port/")
}

fn collect_from(dirname: &str) -> CollectResult<HashMap<String, SASPort>> {
let mut sasports: HashMap<String, SASPort> = HashMap::new();
let sas_port_path = PathBuf::from(dirname);

let re_phy = match Regex::new(r"^phy-[0-9:]+$") {
Ok(r) => r,
Err(err) => return Err(MetricError::RegexError(err)),
};

let re_expanders = match Regex::new(r"expander-[0-9:]+$") {
Ok(r) => r,
Err(err) => return Err(MetricError::RegexError(err)),
};

let re_end_devices = match Regex::new(r"^end_device-[0-9:]+$") {
Ok(r) => r,
Err(err) => return Err(MetricError::RegexError(err)),
};

for sas_port_item in utils::list_dir_content(&sas_port_path, "", "sas_port") {
let mut sas_port = SASPort::new();
let mut sas_port_item_path = sas_port_path.clone();
sas_port_item_path.push(&sas_port_item);
sas_port_item_path.push("device");

for sas_port_device_item in utils::list_dir_content(&sas_port_item_path, "", "device") {
if re_phy.is_match(&sas_port_device_item) {
sas_port.sas_phys.push(sas_port_device_item)
} else if re_expanders.is_match(&sas_port_device_item) {
sas_port.expanders.push(sas_port_device_item)
} else if re_end_devices.is_match(&sas_port_device_item) {
sas_port.end_devices.push(sas_port_device_item)
}
}

sasports.insert(sas_port_item, sas_port);
}

Ok(sasports)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn sas_port_information() {
let sasports =
collect_from("test_data/fixtures/sys/class/sas_port/").expect("sas ports information");

for (sasport_name, sasport_info) in sasports {
match sasport_name.as_str() {
"port-11:0:2" => {
assert_eq!(sasport_info.sas_phys, ["phy-11:0:6"]);
assert_eq!(sasport_info.expanders.is_empty(), true);
assert_eq!(sasport_info.end_devices, ["end_device-11:0:2"]);
}
"port-11:0:1" => {
assert_eq!(sasport_info.sas_phys, ["phy-11:0:4"]);
assert_eq!(sasport_info.expanders.is_empty(), true);
assert_eq!(sasport_info.end_devices, ["end_device-11:0:1"]);
}
"port-11:0:0" => {
assert_eq!(sasport_info.sas_phys, ["phy-11:0:2"]);
assert_eq!(sasport_info.expanders.is_empty(), true);
assert_eq!(sasport_info.end_devices, ["end_device-11:0:0"]);
}
"port-11:0" => {
assert_eq!(sasport_info.sas_phys.len(), 4);
assert_eq!(sasport_info.expanders, ["expander-11:0"]);
assert_eq!(sasport_info.end_devices.is_empty(), true);
}
"port-11:1" => {
assert_eq!(sasport_info.sas_phys.len(), 4);
assert_eq!(sasport_info.expanders, ["expander-11:1"]);
assert_eq!(sasport_info.end_devices.is_empty(), true);
}
_ => panic!("invalid sas port name: {}", sasport_name),
}
}
}
}
1 change: 1 addition & 0 deletions src/sysfs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod class_nvme;
pub mod class_power_supply;
pub mod class_sas_device;
pub mod class_sas_host;
pub mod class_sas_port;
pub mod class_scsi_tape;
pub mod class_thermal;
pub mod class_watchdog;
Expand Down

0 comments on commit 3db73af

Please sign in to comment.