mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-30 06:54:01 +00:00
Merge pull request #62572 from joelsmith/master
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Prevent virtual infinite loop in volume controller **What this PR does / why we need it**: In WatchPod(), if one of the two channels being watched (pod updates and events) is closed, the for/select loop turns into a tight infinite loop because the select immediately falls through due to the channel being closed. This PR changes WatchPod() to Watch the two channels independently instead. **Which issue(s) this PR fixes**: Fixes #62571 **Release note**: ```release-note Fix potential infinite loop that can occur when NFS PVs are recycled. ```
This commit is contained in:
commit
0eb364a313
@ -18,6 +18,7 @@ package recyclerclient
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/core/v1"
|
||||
@ -191,6 +192,8 @@ func (c *realRecyclerClient) Event(eventtype, message string) {
|
||||
c.recorder(eventtype, message)
|
||||
}
|
||||
|
||||
// WatchPod watches a pod and events related to it. It sends pod updates and events over the returned channel
|
||||
// It will continue until stopChannel is closed
|
||||
func (c *realRecyclerClient) WatchPod(name, namespace string, stopChannel chan struct{}) (<-chan watch.Event, error) {
|
||||
podSelector, err := fields.ParseSelector("metadata.name=" + name)
|
||||
if err != nil {
|
||||
@ -217,13 +220,34 @@ func (c *realRecyclerClient) WatchPod(name, namespace string, stopChannel chan s
|
||||
}
|
||||
|
||||
eventCh := make(chan watch.Event, 30)
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
|
||||
go func() {
|
||||
defer close(eventCh)
|
||||
wg.Wait()
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer eventWatch.Stop()
|
||||
defer wg.Done()
|
||||
for {
|
||||
select {
|
||||
case _ = <-stopChannel:
|
||||
return
|
||||
case eventEvent, ok := <-eventWatch.ResultChan():
|
||||
if !ok {
|
||||
return
|
||||
} else {
|
||||
eventCh <- eventEvent
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer podWatch.Stop()
|
||||
defer close(eventCh)
|
||||
var podWatchChannelClosed bool
|
||||
var eventWatchChannelClosed bool
|
||||
defer wg.Done()
|
||||
for {
|
||||
select {
|
||||
case <-stopChannel:
|
||||
@ -231,19 +255,10 @@ func (c *realRecyclerClient) WatchPod(name, namespace string, stopChannel chan s
|
||||
|
||||
case podEvent, ok := <-podWatch.ResultChan():
|
||||
if !ok {
|
||||
podWatchChannelClosed = true
|
||||
return
|
||||
} else {
|
||||
eventCh <- podEvent
|
||||
}
|
||||
case eventEvent, ok := <-eventWatch.ResultChan():
|
||||
if !ok {
|
||||
eventWatchChannelClosed = true
|
||||
} else {
|
||||
eventCh <- eventEvent
|
||||
}
|
||||
}
|
||||
if podWatchChannelClosed && eventWatchChannelClosed {
|
||||
break
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
Loading…
Reference in New Issue
Block a user