mirror of
https://github.com/henrygd/beszel.git
synced 2026-03-21 21:26:16 +01:00
fix: dedupe root-mirrored extra filesystems during disk discovery (#1428)
This commit is contained in:
@@ -197,9 +197,60 @@ func (a *Agent) initializeDiskInfo() {
|
||||
a.fsStats[rootKey] = &system.FsStats{Root: true, Mountpoint: rootMountPoint}
|
||||
}
|
||||
|
||||
a.pruneDuplicateRootExtraFilesystems()
|
||||
a.initializeDiskIoStats(diskIoCounters)
|
||||
}
|
||||
|
||||
// Removes extra filesystems that mirror root usage (https://github.com/henrygd/beszel/issues/1428).
|
||||
func (a *Agent) pruneDuplicateRootExtraFilesystems() {
|
||||
var rootMountpoint string
|
||||
for _, stats := range a.fsStats {
|
||||
if stats != nil && stats.Root {
|
||||
rootMountpoint = stats.Mountpoint
|
||||
break
|
||||
}
|
||||
}
|
||||
if rootMountpoint == "" {
|
||||
return
|
||||
}
|
||||
rootUsage, err := disk.Usage(rootMountpoint)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for name, stats := range a.fsStats {
|
||||
if stats == nil || stats.Root {
|
||||
continue
|
||||
}
|
||||
extraUsage, err := disk.Usage(stats.Mountpoint)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if hasSameDiskUsage(rootUsage, extraUsage) {
|
||||
slog.Info("Ignoring duplicate FS", "name", name, "mount", stats.Mountpoint)
|
||||
delete(a.fsStats, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// hasSameDiskUsage compares root/extra usage with a small byte tolerance.
|
||||
func hasSameDiskUsage(a, b *disk.UsageStat) bool {
|
||||
if a == nil || b == nil || a.Total == 0 || b.Total == 0 {
|
||||
return false
|
||||
}
|
||||
// Allow minor drift between sequential disk usage calls.
|
||||
const toleranceBytes uint64 = 16 * 1024 * 1024
|
||||
return withinUsageTolerance(a.Total, b.Total, toleranceBytes) &&
|
||||
withinUsageTolerance(a.Used, b.Used, toleranceBytes)
|
||||
}
|
||||
|
||||
// withinUsageTolerance reports whether two byte values differ by at most tolerance.
|
||||
func withinUsageTolerance(a, b, tolerance uint64) bool {
|
||||
if a >= b {
|
||||
return a-b <= tolerance
|
||||
}
|
||||
return b-a <= tolerance
|
||||
}
|
||||
|
||||
// Returns matching device from /proc/diskstats.
|
||||
// bool is true if a match was found.
|
||||
func findIoDevice(filesystem string, diskIoCounters map[string]disk.IOCountersStat) (string, bool) {
|
||||
|
||||
@@ -372,3 +372,37 @@ func TestDiskUsageCaching(t *testing.T) {
|
||||
"lastDiskUsageUpdate should be refreshed when cache expires")
|
||||
})
|
||||
}
|
||||
|
||||
func TestHasSameDiskUsage(t *testing.T) {
|
||||
const toleranceBytes uint64 = 16 * 1024 * 1024
|
||||
|
||||
t.Run("returns true when totals and usage are equal", func(t *testing.T) {
|
||||
a := &disk.UsageStat{Total: 100 * 1024 * 1024 * 1024, Used: 42 * 1024 * 1024 * 1024}
|
||||
b := &disk.UsageStat{Total: 100 * 1024 * 1024 * 1024, Used: 42 * 1024 * 1024 * 1024}
|
||||
assert.True(t, hasSameDiskUsage(a, b))
|
||||
})
|
||||
|
||||
t.Run("returns true within tolerance", func(t *testing.T) {
|
||||
a := &disk.UsageStat{Total: 100 * 1024 * 1024 * 1024, Used: 42 * 1024 * 1024 * 1024}
|
||||
b := &disk.UsageStat{
|
||||
Total: a.Total + toleranceBytes - 1,
|
||||
Used: a.Used - toleranceBytes + 1,
|
||||
}
|
||||
assert.True(t, hasSameDiskUsage(a, b))
|
||||
})
|
||||
|
||||
t.Run("returns false when total exceeds tolerance", func(t *testing.T) {
|
||||
a := &disk.UsageStat{Total: 100 * 1024 * 1024 * 1024, Used: 42 * 1024 * 1024 * 1024}
|
||||
b := &disk.UsageStat{
|
||||
Total: a.Total + toleranceBytes + 1,
|
||||
Used: a.Used,
|
||||
}
|
||||
assert.False(t, hasSameDiskUsage(a, b))
|
||||
})
|
||||
|
||||
t.Run("returns false for nil or zero total", func(t *testing.T) {
|
||||
assert.False(t, hasSameDiskUsage(nil, &disk.UsageStat{Total: 1, Used: 1}))
|
||||
assert.False(t, hasSameDiskUsage(&disk.UsageStat{Total: 1, Used: 1}, nil))
|
||||
assert.False(t, hasSameDiskUsage(&disk.UsageStat{Total: 0, Used: 0}, &disk.UsageStat{Total: 1, Used: 1}))
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user