From f57fc611c2135ae2cb3bd248b0d86f5bc7659445 Mon Sep 17 00:00:00 2001 From: Andrej Date: Sun, 3 Aug 2025 10:41:33 -0400 Subject: [PATCH] uz801: Use busybox coreutils (they were hiding all along) --- daemon/src/stats.rs | 123 ++++++++++++-------------------------------- 1 file changed, 34 insertions(+), 89 deletions(-) diff --git a/daemon/src/stats.rs b/daemon/src/stats.rs index 2b0eac0..0b5e90d 100644 --- a/daemon/src/stats.rs +++ b/daemon/src/stats.rs @@ -40,58 +40,30 @@ pub struct DiskStats { impl DiskStats { // runs "df -h " to get storage statistics for the partition containing - // the QMDL file. The Uz801 device doesn't support the -h flag, so we skip it for that device. + // the QMDL file. pub async fn new(qmdl_path: &str, device: &Device) -> Result { - let mut df_cmd = Command::new("df"); - // Only add -h flag for devices other than Uz801, as Uz801's df doesn't support it - if !matches!(device, Device::Uz801) { - df_cmd.arg("-h"); + // Uz801 needs to be told to use the busybox df specifically + let mut df_cmd: Command; + if matches!(device, Device::Uz801) { + df_cmd = Command::new("busybox"); + df_cmd.arg("df"); + } else { + df_cmd = Command::new("df"); } + df_cmd.arg("-h"); df_cmd.arg(qmdl_path); let stdout = get_cmd_output(df_cmd).await?; - if matches!(device, Device::Uz801) { - // Handle Uz801 format: - // Filesystem Size Used Free Blksize - // /data/rayhunter/ 774.9M 68.0M 706.9M 4096 - let lines: Vec<&str> = stdout.lines().collect(); - if lines.len() < 2 { - return Err("error parsing df output: insufficient lines".to_string()); - } - let data_line = lines[1]; - let mut parts = data_line.split_whitespace(); - Ok(Self { - partition: parts - .next() - .ok_or("error parsing df output: missing filesystem")? - .to_string(), - total_size: parts - .next() - .ok_or("error parsing df output: missing size")? - .to_string(), - used_size: parts - .next() - .ok_or("error parsing df output: missing used")? - .to_string(), - available_size: parts - .next() - .ok_or("error parsing df output: missing free")? - .to_string(), - used_percent: "N/A".to_string(), // Uz801 df doesn't provide percentage - mounted_on: qmdl_path.to_string(), // Use the path we queried - }) - } else { - // Handle standard df -h format - let mut parts = stdout.split_whitespace().skip(7); - Ok(Self { - partition: parts.next().ok_or("error parsing df output")?.to_string(), - total_size: parts.next().ok_or("error parsing df output")?.to_string(), - used_size: parts.next().ok_or("error parsing df output")?.to_string(), - available_size: parts.next().ok_or("error parsing df output")?.to_string(), - used_percent: parts.next().ok_or("error parsing df output")?.to_string(), - mounted_on: parts.next().ok_or("error parsing df output")?.to_string(), - }) - } + // Handle standard df -h format + let mut parts = stdout.split_whitespace().skip(7); + Ok(Self { + partition: parts.next().ok_or("error parsing df output")?.to_string(), + total_size: parts.next().ok_or("error parsing df output")?.to_string(), + used_size: parts.next().ok_or("error parsing df output")?.to_string(), + available_size: parts.next().ok_or("error parsing df output")?.to_string(), + used_percent: parts.next().ok_or("error parsing df output")?.to_string(), + mounted_on: parts.next().ok_or("error parsing df output")?.to_string(), + }) } } @@ -121,52 +93,25 @@ async fn get_cmd_output(mut cmd: Command) -> Result { impl MemoryStats { // runs "free -k" and parses the output to retrieve memory stats for most devices, - // or reads /proc/meminfo for Uz801 which doesn't have the free command pub async fn new(device: &Device) -> Result { + // Use busybox for Uz801 + let mut free_cmd: Command; if matches!(device, Device::Uz801) { - // Read /proc/meminfo for Uz801 - let meminfo_content = tokio::fs::read_to_string("/proc/meminfo") - .await - .map_err(|e| format!("error reading /proc/meminfo: {}", e))?; - - let mut mem_total_kb = None; - let mut mem_free_kb = None; - - for line in meminfo_content.lines() { - if let Some(value_str) = line.strip_prefix("MemTotal:") { - if let Some(kb_str) = value_str.trim().strip_suffix(" kB") { - mem_total_kb = kb_str.trim().parse::().ok(); - } - } else if let Some(value_str) = line.strip_prefix("MemFree:") { - if let Some(kb_str) = value_str.trim().strip_suffix(" kB") { - mem_free_kb = kb_str.trim().parse::().ok(); - } - } - } - - let total = mem_total_kb.ok_or("error parsing MemTotal from /proc/meminfo")?; - let free = mem_free_kb.ok_or("error parsing MemFree from /proc/meminfo")?; - let used = total - free; - - Ok(Self { - total: humanize_kb(total), - used: humanize_kb(used), - free: humanize_kb(free), - }) + free_cmd = Command::new("busybox"); + free_cmd.arg("free"); } else { - // Use free command for other devices - let mut free_cmd = Command::new("free"); - free_cmd.arg("-k"); - let stdout = get_cmd_output(free_cmd).await?; - let mut numbers = stdout - .split_whitespace() - .flat_map(|part| part.parse::()); - Ok(Self { - total: humanize_kb(numbers.next().ok_or("error parsing free output")?), - used: humanize_kb(numbers.next().ok_or("error parsing free output")?), - free: humanize_kb(numbers.next().ok_or("error parsing free output")?), - }) + free_cmd = Command::new("free"); } + free_cmd.arg("-k"); + let stdout = get_cmd_output(free_cmd).await?; + let mut numbers = stdout + .split_whitespace() + .flat_map(|part| part.parse::()); + Ok(Self { + total: humanize_kb(numbers.next().ok_or("error parsing free output")?), + used: humanize_kb(numbers.next().ok_or("error parsing free output")?), + free: humanize_kb(numbers.next().ok_or("error parsing free output")?), + }) } }