fix: Exclude TrueNAS Docker overlay mounts from disk stats

Host agent was including Docker overlay2 mounts from TrueNAS SCALE's
.ix-apps directory in disk totals. These mounts inherit the ZFS pool's
AVAIL space, causing massively inflated storage numbers (e.g., 173 TB
per container overlay instead of actual usage).

Changes:
- Add /mnt/.ix-apps/docker/ to container overlay path exclusions
- Use ShouldSkipFilesystem() in host agent disk collection (was only
  using ShouldIgnoreReadOnlyFilesystem() which missed container paths)
- Add test cases for TrueNAS overlay paths

Related to #718
This commit is contained in:
rcourtman 2025-12-04 03:03:04 +00:00
parent 284afbbda1
commit 29e4f54243
3 changed files with 25 additions and 4 deletions

View file

@ -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
}

View file

@ -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
}

View file

@ -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},