mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-10 23:26:53 +00:00
scanner status command(1)
Signed-off-by: mujunxiang <1948535941@qq.com>
This commit is contained in:
@@ -6,5 +6,6 @@ pub mod hash;
|
||||
pub mod net;
|
||||
pub mod os;
|
||||
pub mod path;
|
||||
pub mod time;
|
||||
pub mod wildcard;
|
||||
pub mod xml;
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
use nix::sys::stat::{self, stat};
|
||||
use nix::sys::statfs::{self, statfs, FsType};
|
||||
use std::io::{Error, ErrorKind};
|
||||
use std::fs::File;
|
||||
use std::io::{self, BufRead, Error, ErrorKind};
|
||||
use std::path::Path;
|
||||
|
||||
use crate::{disk::Info, error::Result};
|
||||
use crate::{
|
||||
disk::Info,
|
||||
error::{Error as e_Error, Result},
|
||||
};
|
||||
|
||||
use super::IOStats;
|
||||
|
||||
/// returns total and free bytes available in a directory, e.g. `/`.
|
||||
pub fn get_info(p: impl AsRef<Path>) -> std::io::Result<Info> {
|
||||
@@ -110,3 +116,72 @@ pub fn same_disk(disk1: &str, disk2: &str) -> Result<bool> {
|
||||
|
||||
Ok(stat1.st_dev == stat2.st_dev)
|
||||
}
|
||||
|
||||
pub fn get_drive_stats(major: u32, minor: u32) -> Result<IOStats> {
|
||||
read_drive_stats(&format!("/sys/dev/block/{}:{}/stat", major, minor))
|
||||
}
|
||||
|
||||
fn read_drive_stats(stats_file: &str) -> Result<IOStats> {
|
||||
let stats = read_stat(stats_file)?;
|
||||
if stats.len() < 11 {
|
||||
return Err(e_Error::from_string(format!("found invalid format while reading {}", stats_file)));
|
||||
}
|
||||
let mut io_stats = IOStats {
|
||||
read_ios: stats[0],
|
||||
read_merges: stats[1],
|
||||
read_sectors: stats[2],
|
||||
read_ticks: stats[3],
|
||||
write_ios: stats[4],
|
||||
write_merges: stats[5],
|
||||
write_sectors: stats[6],
|
||||
write_ticks: stats[7],
|
||||
current_ios: stats[8],
|
||||
total_ticks: stats[9],
|
||||
req_ticks: stats[10],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
if stats.len() > 14 {
|
||||
io_stats.discard_ios = stats[11];
|
||||
io_stats.discard_merges = stats[12];
|
||||
io_stats.discard_sectors = stats[13];
|
||||
io_stats.discard_ticks = stats[14];
|
||||
}
|
||||
Ok(io_stats)
|
||||
}
|
||||
|
||||
fn read_stat(file_name: &str) -> Result<Vec<u64>> {
|
||||
// 打开文件
|
||||
let path = Path::new(file_name);
|
||||
let file = File::open(&path)?;
|
||||
|
||||
// 创建一个 BufReader
|
||||
let reader = io::BufReader::new(file);
|
||||
|
||||
// 读取第一行
|
||||
let mut stats = Vec::new();
|
||||
for line in reader.lines() {
|
||||
let line = line?;
|
||||
// 分割行并解析为 u64
|
||||
for token in line.trim().split_whitespace() {
|
||||
let ui64: u64 = token.parse()?;
|
||||
stats.push(ui64);
|
||||
}
|
||||
break; // 只读取第一行
|
||||
}
|
||||
|
||||
Ok(stats)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::get_drive_stats;
|
||||
|
||||
#[test]
|
||||
fn test_stats() {
|
||||
let major = 7;
|
||||
let minor = 11;
|
||||
let s = get_drive_stats(major, minor).unwrap();
|
||||
println!("{:?}", s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,31 @@ mod unix;
|
||||
mod windows;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub use linux::{get_info, same_disk};
|
||||
pub use linux::{get_drive_stats, get_info, same_disk};
|
||||
// pub use linux::same_disk;
|
||||
|
||||
#[cfg(all(unix, not(target_os = "linux")))]
|
||||
pub use unix::{get_info, same_disk};
|
||||
pub use unix::{get_drive_stats, get_info, same_disk};
|
||||
#[cfg(target_os = "windows")]
|
||||
pub use windows::{get_info, same_disk};
|
||||
pub use windows::{get_drive_stats, get_info, same_disk};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct IOStats {
|
||||
pub read_ios: u64,
|
||||
pub read_merges: u64,
|
||||
pub read_sectors: u64,
|
||||
pub read_ticks: u64,
|
||||
pub write_ios: u64,
|
||||
pub write_merges: u64,
|
||||
pub write_sectors: u64,
|
||||
pub write_ticks: u64,
|
||||
pub current_ios: u64,
|
||||
pub total_ticks: u64,
|
||||
pub req_ticks: u64,
|
||||
pub discard_ios: u64,
|
||||
pub discard_merges: u64,
|
||||
pub discard_sectors: u64,
|
||||
pub discard_ticks: u64,
|
||||
pub flush_ios: u64,
|
||||
pub flush_ticks: u64,
|
||||
}
|
||||
|
||||
@@ -75,3 +75,7 @@ pub fn same_disk(disk1: &str, disk2: &str) -> Result<bool> {
|
||||
|
||||
Ok(stat1.st_dev == stat2.st_dev)
|
||||
}
|
||||
|
||||
pub fn get_drive_stats(major: u32, minor: u32) -> Result<IOStats> {
|
||||
IOStats::default()
|
||||
}
|
||||
|
||||
@@ -134,3 +134,7 @@ fn get_fs_type(p: &[WCHAR]) -> Result<String> {
|
||||
pub fn same_disk(disk1: &str, disk2: &str) -> Result<bool> {
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
pub fn get_drive_stats(major: u32, minor: u32) -> Result<IOStats> {
|
||||
IOStats::default()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use tracing::info;
|
||||
|
||||
pub fn parse_duration(s: &str) -> Option<Duration> {
|
||||
if s.ends_with("ms") {
|
||||
if let Ok(s) = s.trim_end_matches("ms").parse::<u64>() {
|
||||
return Some(Duration::from_millis(s));
|
||||
}
|
||||
} else if s.ends_with("s") {
|
||||
if let Ok(s) = s.trim_end_matches('s').parse::<u64>() {
|
||||
return Some(Duration::from_secs(s));
|
||||
}
|
||||
} else if s.ends_with("m") {
|
||||
if let Ok(s) = s.trim_end_matches('m').parse::<u64>() {
|
||||
return Some(Duration::from_secs(s * 60));
|
||||
}
|
||||
} else if s.ends_with("h") {
|
||||
if let Ok(s) = s.trim_end_matches('h').parse::<u64>() {
|
||||
return Some(Duration::from_secs(s * 60 * 60));
|
||||
}
|
||||
}
|
||||
info!("can not parse duration, s: {}", s);
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::time::Duration;
|
||||
|
||||
use super::parse_duration;
|
||||
|
||||
#[test]
|
||||
fn test_parse_dur() {
|
||||
let s = String::from("3s");
|
||||
let dur = parse_duration(&s);
|
||||
println!("{:?}", dur);
|
||||
assert_eq!(Some(Duration::from_secs(3)), dur);
|
||||
|
||||
let s = String::from("3ms");
|
||||
let dur = parse_duration(&s);
|
||||
println!("{:?}", dur);
|
||||
assert_eq!(Some(Duration::from_millis(3)), dur);
|
||||
|
||||
let s = String::from("3m");
|
||||
let dur = parse_duration(&s);
|
||||
println!("{:?}", dur);
|
||||
assert_eq!(Some(Duration::from_secs(3 * 60)), dur);
|
||||
|
||||
let s = String::from("3h");
|
||||
let dur = parse_duration(&s);
|
||||
println!("{:?}", dur);
|
||||
assert_eq!(Some(Duration::from_secs(3 * 60 * 60)), dur);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user