Change:
A CSI plugin that the 1.10 controller manager can't detect (which could occur in a number of scenarios, such as when a rollout is being performed or a node is evacuated) seems to retry without backoff. In this case, I have a pod referencing a PVC -PV that references my CSI plugin, but no controller plugin running. The controller is probing every 100ms continuously for a single volume attachment. The controller should backoff. Have not tested with higher numbers of pods, but in a busy system this could cause the controller manager to burn CPU. Also, there isn't actually a great error telling the user why the probing is happening (I knew in this case, but an admin likely has no idea).
/assign
Issues go stale after 90d of inactivity. Mark the issue as fresh with . Stale issues rot after an additional 30d of inactivity and eventually close. If this issue is safe to close now please do so with . Send feedback to sig-testing, kubernetes/test-infra and/or . /lifecycle stale
/remove-lifecycle stale /milestone v1.14 adding it to next milestone as per if it doesn't make it then it can be further moved
as KEP has been moved, unless an exception is made, /milestone v1.15
the linked kep above is unrelated to this issue. This is a bug and I don't think it needs an associated enhancement
sorry, got diverted by the comments on that KEP. /milestone v1.14
Hello from Bug Triage Shadow . I'd like to remind that code freeze is coming in 3 days (Friday, 8th March). Is this still planned to be fixed for 1.14?
We have not been tracking this for 1.14. /assign can you help triage and see if this is still an issue and if there is a quick fix?
I can't reproduce the issue, do you remember what you did? From the logs it seems that Watch channel consistently returns so new is called recursively (beware, 1.10 code, but it's very similar in master): Can it produce fairly stable 100ms delay between calls? Anyway, this is not usual code path, watcher does not return in most cases. if I read the code correctly, such recursive must end up with timeout - caller does not care about return value and caller's watch probably won't return anything useful. Is there a reason why we don't return error? This will kick in exponential backoff in A/D controller.
clearing the milestone for tracking purposes to let the fix land in its own time /milestone clear
Issues go stale after 90d of inactivity. Mark the issue as fresh with . Stale issues rot after an additional 30d of inactivity and eventually close. If this issue is safe to close now please do so with . Send feedback to sig-testing, kubernetes/test-infra and/or . /lifecycle stale
I found the error would happen when a pv is attahing(volumeattachment has created) and the csi-attacher is deleted at the same time. Then the log would print so frequently (because of recursion).
is this fixed by ?
Stale issues rot after 30d of inactivity. Mark the issue as fresh with . Rotten issues close after an additional 30d of inactivity. If this issue is safe to close now please do so with . Send feedback to sig-testing, kubernetes/test-infra and/or . /lifecycle rotten
Rotten issues close after 30d of inactivity. Reopen the issue with . Mark the issue as fresh with . Send feedback to sig-testing, kubernetes/test-infra and/or . /close
Closing this issue. <detailsIn response to : Rotten issues close after 30d of inactivity. Reopen the issue with . Mark the issue as fresh with . /close Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details

Discussion:
if err != nil { return fmt.Errorf("watch error:%v for volume %v", err, volumeHandle) } <del> var watcherClosed bool ch := watcher.ResultChan() defer func() { if !watcherClosed { watcher.Stop() } }() </del> <ins> ch := watcher.ResultChan() defer watcher.Stop() </ins> for { select { case event, ok := <-ch:

return nil case watch.Error: <del> watcher.Stop() watcherClosed = true // start another cycle return c.waitForVolumeDetachmentInternal(volumeHandle, attachID, timer, timeout) </del> <ins> klog.Warningf("waitForVolumeDetachmentInternal received watch error: %v", event) </ins> } case <-timer.C:

nodeName := "test-node" testCases := []struct { <del> name       string volID      string attachID   string shouldFail bool reactor    func(action core.Action) (handled bool, ret runtime.Object, err error) </del> <ins> name         string volID        string attachID     string shouldFail   bool watcherError bool reactor      func(action core.Action) (handled bool, ret runtime.Object, err error) </ins> }{ {name: "normal test", volID: "vol-001", attachID: getAttachmentName("vol-001", testDriver, nodeName)}, {name: "normal test 2", volID: "vol-002", attachID: getAttachmentName("vol-002", testDriver, nodeName)},

return false, nil, nil }, }, <ins> { name:         "API watch error happen", volID:        "vol-005", attachID:     getAttachmentName("vol-005", testDriver, nodeName), shouldFail:   true, watcherError: true, reactor: func(action core.Action) (handled bool, ret runtime.Object, err error) { if action.Matches("get", "volumeattachments") { return true, makeTestAttachment(getAttachmentName("vol-005", testDriver, nodeName), nodeName, "vol-005"), nil } return false, nil, nil }, }, </ins> } for _, tc := range testCases {

if err != nil { t.Errorf("test case %s failed: %v", tc.name, err) } <ins> watchError := tc.watcherError csiAttacher.waitSleepTime = 100 * time.Millisecond </ins> go func() { <ins> if watchError { errStatus := apierrs.NewInternalError(fmt.Errorf("we got an error")).Status() fakeWatcher.Error(&errStatus) return } </ins> fakeWatcher.Delete(attachment) }() err = csiAttacher.Detach(volumeName, types.NodeName(nodeName))