Skip to content

Commit c0a7d0c

Browse files
committed
fix: add cooldown to health monitor unmount to prevent log spam
After force-unmounting a broken staging path, suppress repeated attempts for the same path for 5 minutes. This prevents noisy warning logs when kubelet is slow to re-stage (e.g., deep CrashLoopBackOff backoff).
1 parent ef63eb3 commit c0a7d0c

2 files changed

Lines changed: 23 additions & 0 deletions

File tree

pkg/driver/node.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"path/filepath"
88
"strings"
99
"syscall"
10+
"time"
1011

1112
"github.com/container-storage-interface/spec/lib/go/csi"
1213
"github.com/nasty-project/nasty-csi/pkg/metrics"
@@ -43,6 +44,7 @@ type NodeService struct {
4344
nodeRegistry *NodeRegistry
4445
nvmeConnectSem chan struct{}
4546
stopCh chan struct{}
47+
recentUnmounts map[string]time.Time // tracks recently unmounted staging paths to avoid log spam
4648
nodeID string
4749
testMode bool
4850
enableDiscovery bool
@@ -61,6 +63,7 @@ func NewNodeService(nodeID string, apiClient nastyapi.ClientInterface, testMode
6163
enableDiscovery: enableDiscovery,
6264
nvmeConnectSem: make(chan struct{}, maxConcurrentNVMeConnects),
6365
stopCh: make(chan struct{}),
66+
recentUnmounts: make(map[string]time.Time),
6467
}
6568
}
6669

pkg/driver/node_recovery.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ func (s *NodeService) runHealthCheck() {
8181
s.unmountBrokenStagingPaths(ctx)
8282
}
8383

84+
// unmountCooldown is how long we suppress repeated unmount attempts for the
85+
// same staging path. This prevents log spam when kubelet is slow to re-stage.
86+
const unmountCooldown = 5 * time.Minute
87+
8488
// unmountBrokenStagingPaths finds staging mounts where the source block device
8589
// no longer exists and force-unmounts them so kubelet can re-stage.
8690
func (s *NodeService) unmountBrokenStagingPaths(ctx context.Context) {
@@ -95,6 +99,14 @@ func (s *NodeService) unmountBrokenStagingPaths(ctx context.Context) {
9599
return
96100
}
97101

102+
// Expire old entries from the cooldown map
103+
now := time.Now()
104+
for path, ts := range s.recentUnmounts {
105+
if now.Sub(ts) > unmountCooldown {
106+
delete(s.recentUnmounts, path)
107+
}
108+
}
109+
98110
// Filter for our CSI driver's staging paths
99111
const stagingPathMarker = "/plugins/kubernetes.io/csi/nasty.csi.io/"
100112
for _, line := range strings.Split(string(output), "\n") {
@@ -110,6 +122,11 @@ func (s *NodeService) unmountBrokenStagingPaths(ctx context.Context) {
110122
source := fields[0]
111123
target := fields[1]
112124

125+
// Skip if we recently unmounted this path (avoid log spam)
126+
if _, cooldown := s.recentUnmounts[target]; cooldown {
127+
continue
128+
}
129+
113130
// Check if the source device still exists
114131
if _, statErr := os.Stat(source); statErr == nil {
115132
// Device exists — check if it's actually accessible
@@ -132,6 +149,9 @@ func (s *NodeService) unmountBrokenStagingPaths(ctx context.Context) {
132149
klog.Infof("Successfully unmounted broken staging path %s — kubelet will re-stage", target)
133150
}
134151
umountCancel()
152+
153+
// Record this unmount to suppress repeated attempts
154+
s.recentUnmounts[target] = now
135155
}
136156
}
137157

0 commit comments

Comments
 (0)