fix: correct disk size aggregation and nvme temperature detection
This commit is contained in:
parent
689498c5f4
commit
bd0d15a1ae
@ -333,32 +333,42 @@ pub async fn collect_disks(state: &AppState) -> Vec<DiskInfo> {
|
|||||||
disks_list.refresh(false); // don't drop missing disks
|
disks_list.refresh(false); // don't drop missing disks
|
||||||
|
|
||||||
// Collect disk temperatures from components
|
// Collect disk temperatures from components
|
||||||
|
// NVMe temps show up as "Composite" under different chip names
|
||||||
let disk_temps = {
|
let disk_temps = {
|
||||||
let mut components = state.components.lock().await;
|
let mut components = state.components.lock().await;
|
||||||
components.refresh(false);
|
components.refresh(false);
|
||||||
let mut temps = std::collections::HashMap::new();
|
let mut composite_temps = Vec::new();
|
||||||
|
|
||||||
for c in components.iter() {
|
for c in components.iter() {
|
||||||
let label = c.label().to_ascii_lowercase();
|
let label = c.label().to_ascii_lowercase();
|
||||||
// Match common disk/SSD/NVMe sensor labels
|
|
||||||
if (label.contains("nvme") || label.contains("ssd") || label.contains("disk"))
|
// Collect all "Composite" temperatures (these are NVMe drives)
|
||||||
&& let Some(temp) = c.temperature()
|
if label == "composite" && let Some(temp) = c.temperature() {
|
||||||
{
|
composite_temps.push(temp);
|
||||||
// Extract device name from label (e.g., "nvme0" from "Composite nvme0")
|
|
||||||
for part in label.split_whitespace() {
|
|
||||||
if part.starts_with("nvme") || part.starts_with("sd") {
|
|
||||||
temps.insert(part.to_string(), temp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Store composite temps indexed by their order (nvme0n1, nvme1n1, nvme2n1, etc.)
|
||||||
|
let mut temps = std::collections::HashMap::new();
|
||||||
|
for (idx, temp) in composite_temps.iter().enumerate() {
|
||||||
|
temps.insert(format!("nvme{}n1", idx), *temp);
|
||||||
}
|
}
|
||||||
temps
|
temps
|
||||||
};
|
};
|
||||||
|
|
||||||
// First collect all partitions from sysinfo
|
// First collect all partitions from sysinfo, deduplicating by device name
|
||||||
|
// (same partition can be mounted at multiple mount points)
|
||||||
|
let mut seen_partitions = std::collections::HashSet::new();
|
||||||
let partitions: Vec<DiskInfo> = disks_list
|
let partitions: Vec<DiskInfo> = disks_list
|
||||||
.iter()
|
.iter()
|
||||||
.map(|d| {
|
.filter_map(|d| {
|
||||||
let name = d.name().to_string_lossy().into_owned();
|
let name = d.name().to_string_lossy().into_owned();
|
||||||
|
|
||||||
|
// Skip if we've already seen this partition/device
|
||||||
|
if !seen_partitions.insert(name.clone()) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
// Determine if this is a partition
|
// Determine if this is a partition
|
||||||
let is_partition = name.contains("p1")
|
let is_partition = name.contains("p1")
|
||||||
|| name.contains("p2")
|
|| name.contains("p2")
|
||||||
@ -382,13 +392,13 @@ pub async fn collect_disks(state: &AppState) -> Vec<DiskInfo> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
DiskInfo {
|
Some(DiskInfo {
|
||||||
name,
|
name,
|
||||||
total: d.total_space(),
|
total: d.total_space(),
|
||||||
available: d.available_space(),
|
available: d.available_space(),
|
||||||
temperature,
|
temperature,
|
||||||
is_partition,
|
is_partition,
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -402,7 +412,12 @@ pub async fn collect_disks(state: &AppState) -> Vec<DiskInfo> {
|
|||||||
// nvme0n1p1 -> nvme0n1, sda1 -> sda, mmcblk0p1 -> mmcblk0
|
// nvme0n1p1 -> nvme0n1, sda1 -> sda, mmcblk0p1 -> mmcblk0
|
||||||
let parent_name = if let Some(pos) = partition.name.rfind('p') {
|
let parent_name = if let Some(pos) = partition.name.rfind('p') {
|
||||||
// Check if character after 'p' is a digit
|
// Check if character after 'p' is a digit
|
||||||
if partition.name.chars().nth(pos + 1).is_some_and(|c| c.is_ascii_digit()) {
|
if partition
|
||||||
|
.name
|
||||||
|
.chars()
|
||||||
|
.nth(pos + 1)
|
||||||
|
.is_some_and(|c| c.is_ascii_digit())
|
||||||
|
{
|
||||||
&partition.name[..pos]
|
&partition.name[..pos]
|
||||||
} else {
|
} else {
|
||||||
// Handle sda1, sdb2, etc (just trim trailing digit)
|
// Handle sda1, sdb2, etc (just trim trailing digit)
|
||||||
@ -414,9 +429,11 @@ pub async fn collect_disks(state: &AppState) -> Vec<DiskInfo> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Aggregate partition stats into parent
|
// Aggregate partition stats into parent
|
||||||
let entry = parent_disks
|
let entry = parent_disks.entry(parent_name.to_string()).or_insert((
|
||||||
.entry(parent_name.to_string())
|
0,
|
||||||
.or_insert((0, 0, partition.temperature));
|
0,
|
||||||
|
partition.temperature,
|
||||||
|
));
|
||||||
entry.0 += partition.total;
|
entry.0 += partition.total;
|
||||||
entry.1 += partition.available;
|
entry.1 += partition.available;
|
||||||
// Keep temperature if any partition has it
|
// Keep temperature if any partition has it
|
||||||
@ -446,7 +463,12 @@ pub async fn collect_disks(state: &AppState) -> Vec<DiskInfo> {
|
|||||||
if partition.is_partition {
|
if partition.is_partition {
|
||||||
// Find parent disk index
|
// Find parent disk index
|
||||||
let parent_name = if let Some(pos) = partition.name.rfind('p') {
|
let parent_name = if let Some(pos) = partition.name.rfind('p') {
|
||||||
if partition.name.chars().nth(pos + 1).is_some_and(|c| c.is_ascii_digit()) {
|
if partition
|
||||||
|
.name
|
||||||
|
.chars()
|
||||||
|
.nth(pos + 1)
|
||||||
|
.is_some_and(|c| c.is_ascii_digit())
|
||||||
|
{
|
||||||
&partition.name[..pos]
|
&partition.name[..pos]
|
||||||
} else {
|
} else {
|
||||||
partition.name.trim_end_matches(char::is_numeric)
|
partition.name.trim_end_matches(char::is_numeric)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user