File: 0014-fix-goroutine-leak-of-container-Attach.patch

package info (click to toggle)
containerd 1.7.24~ds1-10
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 15,232 kB
  • sloc: sh: 1,356; makefile: 582
file content (82 lines) | stat: -rw-r--r-- 2,886 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
From: wheat2018 <1151937289@qq.com>
Date: Tue, 13 Aug 2024 15:56:31 +0800
Subject: fix goroutine leak of container Attach

The monitor goroutine (runs (*ContainerIO).Attach.func1) of Attach will
never finish if it attaches to a container without any stdout or stderr
output. Wait for http context cancel and break the pipe actively to
address the issue.

Signed-off-by: wheat2018 <1151937289@qq.com>
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
(cherry picked from commit a0d0f0ef68935338d2c710db164fa7820f692530)
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
---
 pkg/cri/io/container_io.go           | 14 +++++++++++---
 pkg/cri/sbserver/container_attach.go |  2 +-
 pkg/cri/server/container_attach.go   |  2 +-
 3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/pkg/cri/io/container_io.go b/pkg/cri/io/container_io.go
index 70bc8b7..e158410 100644
--- a/pkg/cri/io/container_io.go
+++ b/pkg/cri/io/container_io.go
@@ -17,6 +17,7 @@
 package io
 
 import (
+	"context"
 	"errors"
 	"io"
 	"strings"
@@ -134,7 +135,7 @@ func (c *ContainerIO) Pipe() {
 
 // Attach attaches container stdio.
 // TODO(random-liu): Use pools.Copy in docker to reduce memory usage?
-func (c *ContainerIO) Attach(opts AttachOptions) {
+func (c *ContainerIO) Attach(ctx context.Context, opts AttachOptions) {
 	var wg sync.WaitGroup
 	key := util.GenerateID()
 	stdinKey := streamKey(c.id, "attach-"+key, Stdin)
@@ -175,8 +176,15 @@ func (c *ContainerIO) Attach(opts AttachOptions) {
 	}
 
 	attachStream := func(key string, close <-chan struct{}) {
-		<-close
-		logrus.Infof("Attach stream %q closed", key)
+		select {
+		case <-close:
+			logrus.Infof("Attach stream %q closed", key)
+		case <-ctx.Done():
+			logrus.Infof("Attach client of %q cancelled", key)
+			// Avoid writeGroup heap up
+			c.stdoutGroup.Remove(key)
+			c.stderrGroup.Remove(key)
+		}
 		// Make sure stdin gets closed.
 		if stdinStreamRC != nil {
 			stdinStreamRC.Close()
diff --git a/pkg/cri/sbserver/container_attach.go b/pkg/cri/sbserver/container_attach.go
index 8527071..315ac8a 100644
--- a/pkg/cri/sbserver/container_attach.go
+++ b/pkg/cri/sbserver/container_attach.go
@@ -79,6 +79,6 @@ func (c *criService) attachContainer(ctx context.Context, id string, stdin io.Re
 		},
 	}
 	// TODO(random-liu): Figure out whether we need to support historical output.
-	cntr.IO.Attach(opts)
+	cntr.IO.Attach(ctx, opts)
 	return nil
 }
diff --git a/pkg/cri/server/container_attach.go b/pkg/cri/server/container_attach.go
index d7d0096..465b3d8 100644
--- a/pkg/cri/server/container_attach.go
+++ b/pkg/cri/server/container_attach.go
@@ -79,6 +79,6 @@ func (c *criService) attachContainer(ctx context.Context, id string, stdin io.Re
 		},
 	}
 	// TODO(random-liu): Figure out whether we need to support historical output.
-	cntr.IO.Attach(opts)
+	cntr.IO.Attach(ctx, opts)
 	return nil
 }