Skip to content

Commit c7db83b

Browse files
committed
fs: avoid hanging os.Stat() in NodeGetVolumeStats after restart
If a node-plugin pod restarts while the backend (e.g. MDS) is down, NodeGetVolumeStats used to call os.Stat() on the target path immediately after (re)starting the health checker, before the checker had a chance to detect the outage. Since os.Stat() blocks in the kernel on an unresponsive mount, this held the VolumeLock forever and made every later call for that path fail with Aborted. Return early with an "not yet available" condition instead of calling os.Stat() when the checker was just (re)started, for CephFS. Signed-off-by: SanjalKatiyar <sanjaldhir@gmail.com>
1 parent b22ca60 commit c7db83b

1 file changed

Lines changed: 18 additions & 1 deletion

File tree

internal/cephfs/nodeserver.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -950,10 +950,27 @@ func (ns *cephfsNodeServer) NodeGetVolumeStats(
950950
// FileChecker is started with the stagingTargetPath, but we can't
951951
// get the stagingPath from the request easily.
952952
// TODO: resolve the stagingPath like rbd.getStagingPath() does
953+
// NOTE: rbd.getStagingPath() uses os.Stat() internally which
954+
// if called synchronously, could block indefinitely.
955+
956+
// Start the background checker but return
957+
// immediately instead of calling os.Stat() on this goroutine.
958+
// If the mount is unresponsive, os.Stat() would block,
959+
// holding the VolumeLock (acquired above) and preventing all future
960+
// calls for this path from reaching isHealthy().
961+
// The background checker will do the stat(), the next periodic
962+
// call will pick up the result (or detect the 75s timeout).
953963
err = ns.healthChecker.StartChecker(req.GetVolumeId(), targetPath, hc.StatCheckerType)
954964
if err != nil {
955965
log.WarningLog(ctx, "failed to start healthchecker: %v", err)
956966
}
967+
968+
return &csi.NodeGetVolumeStatsResponse{
969+
VolumeCondition: &csi.VolumeCondition{
970+
Abnormal: false,
971+
Message: "health checker started, status not yet available",
972+
},
973+
}, nil
957974
}
958975

959976
// !healthy indicates a problem with the volume
@@ -966,7 +983,7 @@ func (ns *cephfsNodeServer) NodeGetVolumeStats(
966983
}, nil
967984
}
968985

969-
// warning: stat() may hang on an unhealthy volume
986+
// no indefite block, if flow reaches here
970987
stat, err := os.Stat(targetPath)
971988
if err != nil {
972989
if util.IsCorruptedMountError(err) {

0 commit comments

Comments
 (0)