83 lines
2.4 KiB
Diff
83 lines
2.4 KiB
Diff
|
|
From 210d1acba11aee0cb4a543fa97feb9ecfc4ba532 Mon Sep 17 00:00:00 2001
|
||
|
|
From: chenjiankun <chenjiankun1@huawei.com>
|
||
|
|
Date: Tue, 15 Jun 2021 20:51:10 +0800
|
||
|
|
Subject: [PATCH] docker: fix ProcessEvent block when CloseStreams block
|
||
|
|
|
||
|
|
The ProcessEvent function will block if the CloseStreams function block in
|
||
|
|
exit event processing. The reason is the ProcessEvent function is serial
|
||
|
|
processing. So we need add a timeout mechanism to deal with it.
|
||
|
|
|
||
|
|
---
|
||
|
|
components/engine/container/stream/streams.go | 42 ++++++++++++-------
|
||
|
|
1 file changed, 27 insertions(+), 15 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/components/engine/container/stream/streams.go b/components/engine/container/stream/streams.go
|
||
|
|
index 585f9e8e3..1a7ef33d4 100644
|
||
|
|
--- a/components/engine/container/stream/streams.go
|
||
|
|
+++ b/components/engine/container/stream/streams.go
|
||
|
|
@@ -7,6 +7,7 @@ import (
|
||
|
|
"io/ioutil"
|
||
|
|
"strings"
|
||
|
|
"sync"
|
||
|
|
+ "time"
|
||
|
|
|
||
|
|
"github.com/containerd/containerd/cio"
|
||
|
|
"github.com/docker/docker/pkg/broadcaster"
|
||
|
|
@@ -92,27 +93,38 @@ func (c *Config) NewNopInputPipe() {
|
||
|
|
|
||
|
|
// CloseStreams ensures that the configured streams are properly closed.
|
||
|
|
func (c *Config) CloseStreams() error {
|
||
|
|
- var errors []string
|
||
|
|
+ done := make(chan struct{})
|
||
|
|
+ var errorsInLine error
|
||
|
|
|
||
|
|
- if c.stdin != nil {
|
||
|
|
- if err := c.stdin.Close(); err != nil {
|
||
|
|
- errors = append(errors, fmt.Sprintf("error close stdin: %s", err))
|
||
|
|
+ go func() {
|
||
|
|
+ var errors []string
|
||
|
|
+ if c.stdin != nil {
|
||
|
|
+ if err := c.stdin.Close(); err != nil {
|
||
|
|
+ errors = append(errors, fmt.Sprintf("error close stdin: %s", err))
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
- }
|
||
|
|
|
||
|
|
- if err := c.stdout.Clean(); err != nil {
|
||
|
|
- errors = append(errors, fmt.Sprintf("error close stdout: %s", err))
|
||
|
|
- }
|
||
|
|
+ if err := c.stdout.Clean(); err != nil {
|
||
|
|
+ errors = append(errors, fmt.Sprintf("error close stdout: %s", err))
|
||
|
|
+ }
|
||
|
|
|
||
|
|
- if err := c.stderr.Clean(); err != nil {
|
||
|
|
- errors = append(errors, fmt.Sprintf("error close stderr: %s", err))
|
||
|
|
- }
|
||
|
|
+ if err := c.stderr.Clean(); err != nil {
|
||
|
|
+ errors = append(errors, fmt.Sprintf("error close stderr: %s", err))
|
||
|
|
+ }
|
||
|
|
|
||
|
|
- if len(errors) > 0 {
|
||
|
|
- return fmt.Errorf(strings.Join(errors, "\n"))
|
||
|
|
- }
|
||
|
|
+ if len(errors) > 0 {
|
||
|
|
+ errorsInLine = fmt.Errorf(strings.Join(errors, "\n"))
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ close(done)
|
||
|
|
+ }()
|
||
|
|
|
||
|
|
- return nil
|
||
|
|
+ select {
|
||
|
|
+ case <-done:
|
||
|
|
+ return errorsInLine
|
||
|
|
+ case <-time.After(3 * time.Second):
|
||
|
|
+ return fmt.Errorf("close stream timeout")
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
|
||
|
|
// CopyToPipe connects streamconfig with a libcontainerd.IOPipe
|
||
|
|
--
|
||
|
|
2.27.0
|
||
|
|
|