From 62e314a5563c1393c688878f2c08160109b2a4dd Mon Sep 17 00:00:00 2001 From: Louis Jackman Date: Fri, 8 Nov 2019 20:18:43 +0000 Subject: [PATCH] Remove potential Goroutine leak in kubeadm wait.go There are two writes yet only one read on a non-buffered channel that is created locally and not passed anywhere else. Therefore, it could leak one of its two spawned Goroutines if either: * The provided `f` takes longer than an erroneous result from `waiter.WaitForHealthyKubelet`, or; * The provided `f` completes before an erroneous result from `waiter.WaitForHealthyKubelet`. The fix is to add a one-element buffer so that the channel write happens for the second Goroutine in these cases, allowing it to finish and freeing references to the now-buffered channel, letting it to be GC'd. --- cmd/kubeadm/app/util/apiclient/wait.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/kubeadm/app/util/apiclient/wait.go b/cmd/kubeadm/app/util/apiclient/wait.go index 3b309d0e2c6..43c6dc5657a 100644 --- a/cmd/kubeadm/app/util/apiclient/wait.go +++ b/cmd/kubeadm/app/util/apiclient/wait.go @@ -157,7 +157,7 @@ func (w *KubeWaiter) WaitForHealthyKubelet(initalTimeout time.Duration, healthzE // WaitForKubeletAndFunc waits primarily for the function f to execute, even though it might take some time. If that takes a long time, and the kubelet // /healthz continuously are unhealthy, kubeadm will error out after a period of exponential backoff func (w *KubeWaiter) WaitForKubeletAndFunc(f func() error) error { - errorChan := make(chan error) + errorChan := make(chan error, 1) go func(errC chan error, waiter Waiter) { if err := waiter.WaitForHealthyKubelet(40*time.Second, fmt.Sprintf("http://localhost:%d/healthz", kubeadmconstants.KubeletHealthzPort)); err != nil {