Merge pull request #1418 from darfux/fix_handle_resizing_leak

Fix goroutine leak when exec/attach
This commit is contained in:
Akihiro Suda 2020-03-28 22:51:51 +09:00 committed by GitHub
commit dd3c5f08b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 11 deletions

View File

@ -44,6 +44,8 @@ func (c *criService) Attach(ctx context.Context, r *runtime.AttachRequest) (*run
func (c *criService) attachContainer(ctx context.Context, id string, stdin io.Reader, stdout, stderr io.WriteCloser, func (c *criService) attachContainer(ctx context.Context, id string, stdin io.Reader, stdout, stderr io.WriteCloser,
tty bool, resize <-chan remotecommand.TerminalSize) error { tty bool, resize <-chan remotecommand.TerminalSize) error {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
// Get container from our container store. // Get container from our container store.
cntr, err := c.containerStore.Get(id) cntr, err := c.containerStore.Get(id)
if err != nil { if err != nil {
@ -60,7 +62,7 @@ func (c *criService) attachContainer(ctx context.Context, id string, stdin io.Re
if err != nil { if err != nil {
return errors.Wrap(err, "failed to load task") return errors.Wrap(err, "failed to load task")
} }
handleResizing(resize, func(size remotecommand.TerminalSize) { handleResizing(ctx, resize, func(size remotecommand.TerminalSize) {
if err := task.Resize(ctx, uint32(size.Width), uint32(size.Height)); err != nil { if err := task.Resize(ctx, uint32(size.Width), uint32(size.Height)); err != nil {
log.G(ctx).WithError(err).Errorf("Failed to resize task %q console", id) log.G(ctx).WithError(err).Errorf("Failed to resize task %q console", id)
} }

View File

@ -132,7 +132,7 @@ func (c *criService) execInternal(ctx context.Context, container containerd.Cont
return nil, errors.Wrapf(err, "failed to start exec %q", execID) return nil, errors.Wrapf(err, "failed to start exec %q", execID)
} }
handleResizing(opts.resize, func(size remotecommand.TerminalSize) { handleResizing(ctx, opts.resize, func(size remotecommand.TerminalSize) {
if err := process.Resize(ctx, uint32(size.Width), uint32(size.Height)); err != nil { if err := process.Resize(ctx, uint32(size.Width), uint32(size.Height)); err != nil {
log.G(ctx).WithError(err).Errorf("Failed to resize process %q console for container %q", execID, id) log.G(ctx).WithError(err).Errorf("Failed to resize process %q console for container %q", execID, id)
} }

View File

@ -17,6 +17,7 @@ limitations under the License.
package server package server
import ( import (
"context"
"crypto/tls" "crypto/tls"
"io" "io"
"math" "math"
@ -160,9 +161,8 @@ func (s *streamRuntime) PortForward(podSandboxID string, port int32, stream io.R
} }
// handleResizing spawns a goroutine that processes the resize channel, calling resizeFunc for each // handleResizing spawns a goroutine that processes the resize channel, calling resizeFunc for each
// remotecommand.TerminalSize received from the channel. The resize channel must be closed elsewhere to stop the // remotecommand.TerminalSize received from the channel.
// goroutine. func handleResizing(ctx context.Context, resize <-chan remotecommand.TerminalSize, resizeFunc func(size remotecommand.TerminalSize)) {
func handleResizing(resize <-chan remotecommand.TerminalSize, resizeFunc func(size remotecommand.TerminalSize)) {
if resize == nil { if resize == nil {
return return
} }
@ -171,14 +171,18 @@ func handleResizing(resize <-chan remotecommand.TerminalSize, resizeFunc func(si
defer runtime.HandleCrash() defer runtime.HandleCrash()
for { for {
size, ok := <-resize select {
if !ok { case <-ctx.Done():
return return
case size, ok := <-resize:
if !ok {
return
}
if size.Height < 1 || size.Width < 1 {
continue
}
resizeFunc(size)
} }
if size.Height < 1 || size.Width < 1 {
continue
}
resizeFunc(size)
} }
}() }()
} }