use crate::detect::{Row, Rows};
use crate::util::{cmd, human_iec, percent};
pub fn detect() -> Rows {
if let Some(row) = zfs_pool_row() {
return vec![row];
}
let Some(d) = crate::sys::disk_usage("/") else {
return Vec::new();
};
vec![Row::val(format!(
"{} / {} ({}%)",
human_iec(d.used),
human_iec(d.total),
percent(d.used, d.total)
))]
}
fn zfs_pool_row() -> Option<Row> {
let pool = zfs_root_pool()?;
let out = cmd("zpool", &["list", "-Hp", "-o", "size,alloc", &pool])?;
let mut f = out.split_whitespace();
let size: u64 = f.next()?.parse().ok()?;
let alloc: u64 = f.next()?.parse().ok()?;
if size == 0 {
return None;
}
Some(Row::keyed(
format!("Disk ({pool})"),
format!(
"{} / {} ({}%)",
human_iec(alloc),
human_iec(size),
percent(alloc, size)
),
))
}
fn zfs_root_pool() -> Option<String> {
let mounts = std::fs::read_to_string("/proc/mounts").ok()?;
for line in mounts.lines() {
let mut f = line.split_whitespace();
let dev = f.next()?;
let mnt = f.next()?;
let fstype = f.next()?;
if mnt == "/" && fstype == "zfs" {
return dev.split('/').next().map(str::to_string);
}
}
None
}