diff --git a/internal/hostmetrics/collector.go b/internal/hostmetrics/collector.go index 7ef40df..2f2f418 100644 --- a/internal/hostmetrics/collector.go +++ b/internal/hostmetrics/collector.go @@ -148,10 +148,12 @@ func collectDisks(ctx context.Context) []agentshost.Disk { continue } - // Skip read-only filesystems like squashfs (snap mounts), erofs, iso9660, etc. - // These are immutable and always report near-full usage, which causes false alerts. - // See issues #505 (Home Assistant OS) and #690 (Ubuntu snap mounts). - if fsfilters.ShouldIgnoreReadOnlyFilesystem(part.Fstype, usage.Total, usage.Used) { + // Skip filesystems that shouldn't be counted toward disk usage: + // - Read-only filesystems (squashfs, erofs, iso9660) - always report near-full + // - Virtual/pseudo filesystems (tmpfs, devtmpfs, cgroup, etc.) + // - Container overlay paths (Docker/Podman layers on ZFS, including TrueNAS .ix-apps) + // See issues #505, #690, #718, #790. + if shouldSkip, _ := fsfilters.ShouldSkipFilesystem(part.Fstype, part.Mountpoint, usage.Total, usage.Used); shouldSkip { continue } diff --git a/pkg/fsfilters/filters.go b/pkg/fsfilters/filters.go index 8d6b9a4..213f577 100644 --- a/pkg/fsfilters/filters.go +++ b/pkg/fsfilters/filters.go @@ -101,6 +101,12 @@ var containerOverlayPatterns = []string{ "/merged", } +// containerPathPrefixes detect container-related paths that should be excluded +// from disk usage, even if they don't contain "/containers/". +var containerPathPrefixes = []string{ + "/mnt/.ix-apps/docker/", // TrueNAS SCALE Docker overlay mounts +} + // ShouldSkipFilesystem determines if a filesystem should be excluded from disk // usage aggregation. It checks for read-only filesystems, virtual/pseudo filesystems, // network mounts, and special system mountpoints. Returns skip=true if the filesystem @@ -155,5 +161,14 @@ func ShouldSkipFilesystem(fsType, mountpoint string, totalBytes, usedBytes uint6 } } + // Check for container paths that don't follow the /containers/ pattern + // (e.g., TrueNAS SCALE uses /mnt/.ix-apps/docker/overlay2/...). Related to #718. + for _, prefix := range containerPathPrefixes { + if strings.HasPrefix(mountpoint, prefix) { + reasons = append(reasons, "container-overlay") + break + } + } + return len(reasons) > 0, reasons } diff --git a/pkg/fsfilters/filters_test.go b/pkg/fsfilters/filters_test.go index 4af2622..67b7e1b 100644 --- a/pkg/fsfilters/filters_test.go +++ b/pkg/fsfilters/filters_test.go @@ -180,6 +180,10 @@ func TestShouldSkipFilesystem(t *testing.T) { {"custom containers diff", "ext4", "/opt/containers/myapp/diff/layer", 1000000, 500000, true}, {"custom containers overlay2", "ext4", "/data/containers/xyz/overlay2/layer1", 1000000, 500000, true}, + // TrueNAS SCALE Docker overlay paths (issue #718) + {"truenas ix-apps docker overlay2", "zfs", "/mnt/.ix-apps/docker/overlay2/6c9aad59ec9b0bc33d5e374/merged", 173 * 1024 * 1024 * 1024 * 1024, 399 * 1024 * 1024, true}, + {"truenas ix-apps docker overlay2 diff", "zfs", "/mnt/.ix-apps/docker/overlay2/c5e317c7340f9273d394dc0/diff", 173 * 1024 * 1024 * 1024 * 1024, 399 * 1024 * 1024, true}, + // Windows paths {"Windows System Reserved", "NTFS", "System Reserved", 500 * 1024 * 1024, 100 * 1024 * 1024, true}, {"Windows C drive - should NOT skip", "NTFS", "C:\\", 500 * 1024 * 1024 * 1024, 200 * 1024 * 1024 * 1024, false},