Skip to content

Commit

Permalink
Merge pull request #453 from peterdk/feature/link-sata
Browse files Browse the repository at this point in the history
SATA link speeds
  • Loading branch information
nokyan authored Feb 20, 2025
2 parents 073360b + 5ac6758 commit ac4cb1c
Show file tree
Hide file tree
Showing 9 changed files with 250 additions and 64 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ nix = { version = "0.29.0", default-features = false, features = [
num_cpus = "1.16.0"
nvml-wrapper = "0.10.0"
paste = "1.0.15"
path-dedot = "3.1.1"
plotters = { version = "0.3.7", default-features = false, features = [
"area_series",
] }
Expand Down
18 changes: 6 additions & 12 deletions src/ui/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,12 +354,9 @@ impl MainWindow {
#[strong(rename_to = this)]
self,
move |_, key, _, _| {
match key {
gdk::Key::Control_L => {
debug!("Ctrl is being held, halting apps and processes updates");
this.imp().pause_updates.set(true);
}
_ => (),
if key == gdk::Key::Control_L {
debug!("Ctrl is being held, halting apps and processes updates");
this.imp().pause_updates.set(true);
};
glib::Propagation::Proceed
}
Expand All @@ -368,12 +365,9 @@ impl MainWindow {
#[weak]
imp,
move |_, key, _, _| {
match key {
gdk::Key::Control_L => {
debug!("Ctrl has been released, continuing apps and processes updates");
imp.pause_updates.set(false);
}
_ => (),
if key == gdk::Key::Control_L {
debug!("Ctrl has been released, continuing apps and processes updates");
imp.pause_updates.set(false);
};
}
));
Expand Down
24 changes: 13 additions & 11 deletions src/utils/battery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,19 +176,21 @@ impl Battery {
Ok(list)
}

pub fn is_valid_power_supply(path: &PathBuf) -> bool {
pub fn is_valid_power_supply<P: AsRef<Path>>(path: P) -> bool {
let path = path.as_ref();

//type == "Battery"
//scope != "Device" (HID device batteries)
let power_supply_type = std::fs::read_to_string(path.join("type"));
let power_supply_scope = std::fs::read_to_string(path.join("scope"));
if let Ok(power_supply_type) = power_supply_type {
if power_supply_type.trim() == "Battery" {
if power_supply_scope.is_err() || power_supply_scope.unwrap().trim() != "Device" {
return true;
}
}
}
false

let power_supply_type_is_battery = std::fs::read_to_string(path.join("type"))
.map(|ps_type| ps_type.trim() == "Battery")
.unwrap_or_default();

let power_supply_scope_is_not_device = std::fs::read_to_string(path.join("scope"))
.map(|ps_scope| ps_scope.trim() != "Device")
.unwrap_or(true);

power_supply_type_is_battery && power_supply_scope_is_not_device
}

pub fn from_sysfs<P: AsRef<Path>>(sysfs_path: P) -> Battery {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ fn parse_proc_stat<S: AsRef<str>>(stat: S) -> Vec<Result<(u64, u64)>> {
.lines()
.skip(1)
.filter(|line| line.starts_with("cpu"))
.map(|line| parse_proc_stat_line(line))
.map(parse_proc_stat_line)
.collect()
}

Expand Down
105 changes: 88 additions & 17 deletions src/utils/drive.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use super::units::convert_storage;
use crate::i18n::{i18n, i18n_f};
use crate::utils::link::{Link, LinkData};
use anyhow::{bail, Context, Result};
use gtk::gio::{Icon, ThemedIcon};
use lazy_regex::{lazy_regex, Lazy, Regex};
use log::trace;
use path_dedot::ParseDot;
use process_data::pci_slot::PciSlot;
use std::{
collections::HashMap,
Expand All @@ -10,16 +14,16 @@ use std::{
str::FromStr,
};

use super::units::convert_storage;
use crate::i18n::{i18n, i18n_f};
use crate::utils::link::{Link, PcieLink};

const PATH_SYSFS: &str = "/sys/block";

static RE_DRIVE: Lazy<Regex> = lazy_regex!(
r" *(?P<read_ios>[0-9]*) *(?P<read_merges>[0-9]*) *(?P<read_sectors>[0-9]*) *(?P<read_ticks>[0-9]*) *(?P<write_ios>[0-9]*) *(?P<write_merges>[0-9]*) *(?P<write_sectors>[0-9]*) *(?P<write_ticks>[0-9]*) *(?P<in_flight>[0-9]*) *(?P<io_ticks>[0-9]*) *(?P<time_in_queue>[0-9]*) *(?P<discard_ios>[0-9]*) *(?P<discard_merges>[0-9]*) *(?P<discard_sectors>[0-9]*) *(?P<discard_ticks>[0-9]*) *(?P<flush_ios>[0-9]*) *(?P<flush_ticks>[0-9]*)"
);

static RE_ATA_LINK: Lazy<Regex> = lazy_regex!(r"(^link(\d+))$");

static RE_ATA_SLOT: Lazy<Regex> = lazy_regex!(r"(^.+?/ata(\d+))/");

#[derive(Debug)]
pub struct DriveData {
pub inner: Drive,
Expand Down Expand Up @@ -83,11 +87,26 @@ pub enum DriveType {
Unknown,
}

#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
pub enum DriveSlot {
Pci(PciSlot),
Ata(AtaSlot),
#[default]
Unknown,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct AtaSlot {
pub ata_device: u8,
pub ata_link: u8,
}

#[derive(Debug, Clone, Default, Eq)]
pub struct Drive {
pub model: Option<String>,
pub drive_type: DriveType,
pub block_device: String,
pub slot: DriveSlot,
pub sysfs_path: PathBuf,
}

Expand Down Expand Up @@ -145,7 +164,7 @@ impl Drive {
drive.block_device = block_device;
drive.model = drive.model().ok().map(|model| model.trim().to_string());
drive.drive_type = drive.drive_type().unwrap_or_default();

drive.slot = drive.slot().unwrap_or_default();
trace!("Created Drive object of {path:?}: {drive:?}");

drive
Expand Down Expand Up @@ -315,21 +334,73 @@ impl Drive {
/// Will return `Err` if there are errors during
/// reading or parsing, or if the drive link type is not supported
pub fn link(&self) -> Result<Link> {
match self.drive_type {
DriveType::Nvme => self.link_for_nvme(),
_ => bail!("unsupported drive type"),
match self.slot {
DriveSlot::Pci(slot) => Ok(Link::Pcie(LinkData::from_pci_slot(&slot)?)),
DriveSlot::Ata(slot) => Ok(Link::Sata(LinkData::from_ata_slot(&slot)?)),
_ => bail!("unsupported drive connection type"),
}
}

fn link_for_nvme(&self) -> Result<Link> {
let pcie_address_path = self.sysfs_path.join("device").join("address");
let pci_slot = PciSlot::from_str(
&std::fs::read_to_string(pcie_address_path)
.map(|x| x.trim().to_string())
.context("Could not find PCIe address in sysfs for nvme")?,
)?;
let pcie_link = PcieLink::from_pci_slot(pci_slot)?;
Ok(Link::Pcie(pcie_link))
pub fn slot(&self) -> Result<DriveSlot> {
if let Ok(pci_slot) = self.pci_slot() {
Ok(DriveSlot::Pci(pci_slot))
} else if let Ok(ata_slot) = self.ata_slot() {
Ok(DriveSlot::Ata(ata_slot))
} else {
bail!("unsupported drive slot type")
}
}

fn pci_slot(&self) -> Result<PciSlot> {
let pci_address_path = self.sysfs_path.join("device").join("address");
let pci_address =
std::fs::read_to_string(pci_address_path).map(|x| x.trim().to_string())?;

Ok(PciSlot::from_str(&pci_address)?)
}

fn ata_slot(&self) -> Result<AtaSlot> {
let symlink = std::fs::read_link(&self.sysfs_path)
.context("Could not read sysfs_path as symlink")?
.to_string_lossy()
.to_string();
// ../../devices/pci0000:40/0000:40:08.3/0000:47:00.0/ata25/host24/target24:0:0/24:0:0:0/block/sda

let ata_sub_path_match = RE_ATA_SLOT
.captures(&symlink)
.context("No ata match found, probably no ata device")?;

let ata_sub_path = ata_sub_path_match
.get(1)
.context("No ata match found, probably no ata device")?
.as_str();

let ata_device = ata_sub_path_match
.get(2)
.context("could not match digits in ata")?
.as_str()
.parse::<u8>()?;

let ata_path = Path::new(&self.sysfs_path).join("..").join(ata_sub_path);
let dot_parsed_path = ata_path.parse_dot()?.clone();
let sub_dirs = std::fs::read_dir(dot_parsed_path).context("Could not read ata path")?;

let ata_link = sub_dirs
.filter_map(|x| {
x.ok().and_then(|x| {
RE_ATA_LINK
.captures(&x.file_name().to_string_lossy())
.and_then(|captures| captures.get(2))
.and_then(|capture| capture.as_str().parse::<u8>().ok())
})
})
.next()
.context("No ata link number found")?;

Ok(AtaSlot {
ata_device,
ata_link,
})
}

/// Returns the World-Wide Identification of the drive
Expand Down
6 changes: 3 additions & 3 deletions src/utils/gpu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::{
};

use self::{amd::AmdGpu, intel::IntelGpu, nvidia::NvidiaGpu, other::OtherGpu};
use crate::utils::link::{Link, PcieLink};
use crate::utils::link::{Link, LinkData};
use crate::{
i18n::i18n,
utils::{pci::Device, read_uevent},
Expand All @@ -29,7 +29,7 @@ pub const VID_AMD: u16 = 0x1002;
pub const VID_INTEL: u16 = 0x8086;
pub const VID_NVIDIA: u16 = 0x10DE;

const RE_CARD_ENUMARATOR: Lazy<Regex> = lazy_regex!(r"(\d+)\/?$");
static RE_CARD_ENUMARATOR: Lazy<Regex> = lazy_regex!(r"(\d+)\/?$");

#[derive(Debug)]
pub struct GpuData {
Expand Down Expand Up @@ -532,7 +532,7 @@ impl Gpu {

pub fn link(&self) -> Result<Link> {
if let GpuIdentifier::PciSlot(pci_slot) = self.gpu_identifier() {
let pcie_link = PcieLink::from_pci_slot(pci_slot)?;
let pcie_link = LinkData::from_pci_slot(&pci_slot)?;
Ok(Link::Pcie(pcie_link))
} else {
bail!("Could not retrieve PciSlot from Gpu");
Expand Down
Loading

0 comments on commit ac4cb1c

Please sign in to comment.