Make mergerfs detection more robust to prevent discovery failures
All checks were successful
Build and Release / build-and-release (push) Successful in 2m9s

Skip mergerfs pools with numeric device references (e.g., "1:2")
instead of crashing. This allows regular drive detection to work
even when mergerfs uses non-standard mount formats.

Preserves existing functionality for standard mergerfs setups.
This commit is contained in:
Christoffer Martinsson 2025-11-23 17:19:15 +01:00
parent 9d0f42d55c
commit 2242b5ddfe
5 changed files with 21 additions and 9 deletions

6
Cargo.lock generated
View File

@ -279,7 +279,7 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
[[package]] [[package]]
name = "cm-dashboard" name = "cm-dashboard"
version = "0.1.118" version = "0.1.119"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@ -301,7 +301,7 @@ dependencies = [
[[package]] [[package]]
name = "cm-dashboard-agent" name = "cm-dashboard-agent"
version = "0.1.118" version = "0.1.119"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -324,7 +324,7 @@ dependencies = [
[[package]] [[package]]
name = "cm-dashboard-shared" name = "cm-dashboard-shared"
version = "0.1.118" version = "0.1.119"
dependencies = [ dependencies = [
"chrono", "chrono",
"serde", "serde",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "cm-dashboard-agent" name = "cm-dashboard-agent"
version = "0.1.118" version = "0.1.119"
edition = "2021" edition = "2021"
[dependencies] [dependencies]

View File

@ -202,15 +202,27 @@ impl DiskCollector {
let (total_bytes, used_bytes) = self.get_filesystem_info(&mount_point) let (total_bytes, used_bytes) = self.get_filesystem_info(&mount_point)
.unwrap_or((0, 0)); .unwrap_or((0, 0));
// Parse member paths // Parse member paths - handle both full paths and numeric references
let member_paths: Vec<String> = device_sources let member_paths: Vec<String> = device_sources
.split(':') .split(':')
.map(|s| s.trim().to_string()) .map(|s| s.trim().to_string())
.filter(|s| !s.is_empty()) .filter(|s| !s.is_empty())
.collect(); .collect();
// Skip this pool if we can't parse the member paths (e.g., numeric references like "1:2")
if member_paths.iter().any(|path| !path.starts_with('/')) {
debug!("Skipping mergerfs pool {} with unparseable member paths: {:?}", mount_point, member_paths);
continue;
}
// Categorize as data vs parity drives // Categorize as data vs parity drives
let (data_drives, parity_drives) = self.categorize_pool_drives(&member_paths)?; let (data_drives, parity_drives) = match self.categorize_pool_drives(&member_paths) {
Ok(drives) => drives,
Err(e) => {
debug!("Failed to categorize drives for pool {}: {}. Skipping.", mount_point, e);
continue;
}
};
pools.push(MergerfsPool { pools.push(MergerfsPool {
mount_point, mount_point,
@ -506,7 +518,7 @@ impl Collector for DiskCollector {
let topology = match self.discover_storage() { let topology = match self.discover_storage() {
Ok(topology) => topology, Ok(topology) => topology,
Err(e) => { Err(e) => {
debug!("Storage discovery failed: {}", e); tracing::error!("Storage discovery failed: {}", e);
return Ok(metrics); return Ok(metrics);
} }
}; };

View File

@ -1,6 +1,6 @@
[package] [package]
name = "cm-dashboard" name = "cm-dashboard"
version = "0.1.118" version = "0.1.119"
edition = "2021" edition = "2021"
[dependencies] [dependencies]

View File

@ -1,6 +1,6 @@
[package] [package]
name = "cm-dashboard-shared" name = "cm-dashboard-shared"
version = "0.1.118" version = "0.1.119"
edition = "2021" edition = "2021"
[dependencies] [dependencies]