fix: disque via statvfs() — valeurs identiques à df
Remplace sysinfo::Disks par un appel direct à libc::statvfs("/").
- used = (f_blocks − f_bfree) × f_frsize → correspond à df "Utilisé"
- free = f_bavail × f_frsize → correspond à df "Dispo"
- total = f_blocks × f_frsize
Avant (sysinfo) : used comptait les blocs réservés root → surestimation de ~3-4 Go.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Generated
+1
@@ -250,6 +250,7 @@ dependencies = [
|
||||
name = "nanometrics-agent"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rumqttc",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
||||
@@ -19,6 +19,7 @@ codegen-units = 1
|
||||
|
||||
[dependencies]
|
||||
sysinfo = { version = "0.30", default-features = false }
|
||||
libc = "0.2"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
toml = "0.8"
|
||||
|
||||
+2
-4
@@ -1,5 +1,5 @@
|
||||
use nanometrics_agent::{config, metrics, payload, transport};
|
||||
use sysinfo::{Components, Disks, Networks, System};
|
||||
use sysinfo::{Components, Networks, System};
|
||||
use std::time::{Duration, Instant};
|
||||
use std::sync::mpsc;
|
||||
|
||||
@@ -34,7 +34,6 @@ fn main() {
|
||||
|
||||
let mut sys = System::new();
|
||||
let mut networks = Networks::new_with_refreshed_list();
|
||||
let mut disks = Disks::new_with_refreshed_list();
|
||||
let mut components = Components::new_with_refreshed_list();
|
||||
|
||||
let udp_sender = if cfg.protocols.udp.enabled {
|
||||
@@ -102,9 +101,8 @@ fn main() {
|
||||
}
|
||||
|
||||
if first_slow || now.duration_since(last_slow).as_secs() >= 60 {
|
||||
disks.refresh();
|
||||
if cfg.metrics.disk.udp || cfg.metrics.disk.mqtt {
|
||||
let (used, free, total) = metrics::disk::get(&disks);
|
||||
let (used, free, total) = metrics::disk::get();
|
||||
m.hdd_used = Some(used);
|
||||
m.hdd_free = Some(free);
|
||||
m.hdd_total = Some(total);
|
||||
|
||||
+22
-20
@@ -1,34 +1,36 @@
|
||||
use sysinfo::Disks;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
pub fn get(disks: &Disks) -> (u64, u64, u64) {
|
||||
for disk in disks.list() {
|
||||
let mount = disk.mount_point().to_string_lossy();
|
||||
if mount == "/" {
|
||||
let total = disk.total_space();
|
||||
let free = disk.available_space();
|
||||
let used = total.saturating_sub(free);
|
||||
return (used, free, total);
|
||||
}
|
||||
/// Retourne (used, free, total) en octets pour le système de fichiers racine "/".
|
||||
/// Utilise statvfs() directement pour correspondre exactement aux chiffres de `df` :
|
||||
/// - total = f_blocks × f_frsize
|
||||
/// - used = (f_blocks − f_bfree) × f_frsize (blocs effectivement écrits)
|
||||
/// - free = f_bavail × f_frsize (disponible pour utilisateurs non-root)
|
||||
pub fn get() -> (u64, u64, u64) {
|
||||
let path = b"/\0";
|
||||
let mut stat = MaybeUninit::<libc::statvfs>::uninit();
|
||||
let ret = unsafe { libc::statvfs(path.as_ptr() as *const libc::c_char, stat.as_mut_ptr()) };
|
||||
if ret != 0 {
|
||||
return (0, 0, 0);
|
||||
}
|
||||
if let Some(disk) = disks.list().first() {
|
||||
let total = disk.total_space();
|
||||
let free = disk.available_space();
|
||||
return (total.saturating_sub(free), free, total);
|
||||
}
|
||||
(0, 0, 0)
|
||||
let stat = unsafe { stat.assume_init() };
|
||||
let bsize = stat.f_frsize as u64;
|
||||
let total = stat.f_blocks.saturating_mul(bsize);
|
||||
let used = stat.f_blocks.saturating_sub(stat.f_bfree).saturating_mul(bsize);
|
||||
let free = stat.f_bavail.saturating_mul(bsize);
|
||||
(used, free, total)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use sysinfo::Disks;
|
||||
|
||||
#[test]
|
||||
fn test_disk_coherent() {
|
||||
let disks = Disks::new_with_refreshed_list();
|
||||
let (used, free, total) = get(&disks);
|
||||
let (used, free, total) = get();
|
||||
eprintln!("résultat statvfs : used={used} free={free} total={total}");
|
||||
if total > 0 {
|
||||
assert!(used + free <= total + 1024, "used + free > total");
|
||||
assert!(used + free <= total + 1024 * 1024, "used + free > total");
|
||||
assert!(total > 0, "total doit être > 0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user