From 60cd513a3383dd7fd85c16259110a843eb00fb9a Mon Sep 17 00:00:00 2001 From: Klaus Post Date: Wed, 16 Feb 2022 08:40:18 -0800 Subject: [PATCH] Fix leaked healing goroutines (#14322) Only the first `listAndHeal` would ever be able to write on errCh, blocking all others infinitely. Instead read all errors but return the first non-nil, if any. The intention appears to be that this should cancel on any error, so that part is kept. Regression from #13990 --- cmd/erasure-server-pool.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cmd/erasure-server-pool.go b/cmd/erasure-server-pool.go index 0c4f14d58..4796c64f0 100644 --- a/cmd/erasure-server-pool.go +++ b/cmd/erasure-server-pool.go @@ -1848,7 +1848,15 @@ func (z *erasureServerPools) HealObjects(ctx context.Context, bucket, prefix str } wg.Wait() }() - return <-errCh + var err error + for e := range errCh { + // Save first non-nil error. + if e != nil && err != nil { + err = e + cancel() + } + } + return err } func (z *erasureServerPools) HealObject(ctx context.Context, bucket, object, versionID string, opts madmin.HealOpts) (madmin.HealResultItem, error) {