Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added /sys/class/sas_host #37

Merged
merged 1 commit into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ Supported Features
* ports-*
* target*/\*/block/*

* ✅ `/sys/class/sas_host/<NAME>/`
* device/
* phy-*
* ports-*

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

fn main() {
let sashosts = class_sas_host::collect().expect("sas hosts information");

match serde_json::to_string_pretty(&sashosts) {
Ok(output) => println!("{}", output),
Err(err) => {
log::error!("{}", err);
std::process::exit(1);
}
}
}
88 changes: 88 additions & 0 deletions src/sysfs/class_sas_host.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
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 SASHost {
/// /sys/class/sas_host/<Name>/device/phy-*
pub sas_phys: Vec<String>,

/// /sys/class/sas_host/<Name>/device/ports-*
pub sas_ports: Vec<String>,
}

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

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

fn collect_from(dirname: &str) -> CollectResult<HashMap<String, SASHost>> {
let mut sashosts: HashMap<String, SASHost> = HashMap::new();
let sas_host_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_port = match Regex::new(r"^port-[0-9:]+$") {
Ok(r) => r,
Err(err) => return Err(MetricError::RegexError(err)),
};

for item in utils::list_dir_content(&sas_host_path, "", "sas_host") {
let mut sas_host = SASHost::new();
let mut item_host_path = sas_host_path.clone();
item_host_path.push(&item);
item_host_path.push("device");

for device_item in utils::list_dir_content(&item_host_path, "", &item) {
if re_phy.is_match(&device_item) {
sas_host.sas_phys.push(device_item);
} else if re_port.is_match(&device_item) {
sas_host.sas_ports.push(device_item);
}
}

sashosts.insert(item.clone(), sas_host);
}

Ok(sashosts)
}

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

#[test]
fn sas_host_information() {
let sashosts =
collect_from("test_data/fixtures/sys/class/sas_host/").expect("sas hosts information");

assert_eq!(sashosts.len(), 1);

let sashost = sashosts.get("host11").unwrap();
assert_eq!(sashost.sas_phys.len(), 9);
assert_eq!(sashost.sas_ports.len(), 3);
}
}
1 change: 1 addition & 0 deletions src/sysfs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub mod class_fibrechannel;
pub mod class_nvme;
pub mod class_power_supply;
pub mod class_sas_device;
pub mod class_sas_host;
pub mod class_scsi_tape;
pub mod class_thermal;
pub mod class_watchdog;
Expand Down
Loading