From 0ebaeb1830b42642ae78920afafcadc381053a1e Mon Sep 17 00:00:00 2001
From: chenjiankun <chenjiankun1@huawei.com>
Date: Mon, 30 Aug 2021 20:44:36 +0800
Subject: [PATCH] docker:add timeout for IO.Wait

---
 .../containerd/containerd/process.go          | 40 +++++++++++++------
 1 file changed, 28 insertions(+), 12 deletions(-)

diff --git a/components/engine/vendor/github.com/containerd/containerd/process.go b/components/engine/vendor/github.com/containerd/containerd/process.go
index 4d0dca9f7..a2aaa424b 100644
--- a/components/engine/vendor/github.com/containerd/containerd/process.go
+++ b/components/engine/vendor/github.com/containerd/containerd/process.go
@@ -18,6 +18,7 @@ package containerd
 
 import (
 	"context"
+	"fmt"
 	"strings"
 	"syscall"
 	"time"
@@ -105,6 +106,21 @@ func (p *process) Pid() uint32 {
 	return p.pid
 }
 
+func waitTimeout(io cio.IO, timeout time.Duration) error {
+	done := make(chan struct{})
+	go func() {
+		io.Wait()
+		close(done)
+	}()
+
+	select {
+	case <-done:
+		return nil
+	case <-time.After(timeout):
+		return fmt.Errorf("Wait IO timeout")
+	}
+}
+
 // Start starts the exec process
 func (p *process) Start(ctx context.Context) error {
 	r, err := p.task.client.TaskService().Start(ctx, &tasks.StartRequest{
@@ -112,19 +128,14 @@ func (p *process) Start(ctx context.Context) error {
 		ExecID:      p.id,
 	})
 	if err != nil {
-		done := make(chan struct{})
-		go func() {
-			p.io.Cancel()
-			p.io.Wait()
-			p.io.Close()
-			close(done)
-		}()
-		select {
-		case <-time.After(30 * time.Second):
+		p.io.Cancel()
+
+		errWait := waitTimeout(p.io, 30*time.Second)
+		if errWait != nil {
 			logrus.Warnf("process start failed with error %v, wait io close timeout, some fifo io may be dropped.", err)
-		case <-done:
-			// ok
 		}
+		p.io.Close()
+
 		return errdefs.FromGRPC(err)
 	}
 	p.pid = r.Pid
@@ -221,7 +232,12 @@ func (p *process) Delete(ctx context.Context, opts ...ProcessDeleteOpts) (*ExitS
 	}
 	if p.io != nil {
 		p.io.Cancel()
-		p.io.Wait()
+
+		err := waitTimeout(p.io, 3*time.Second)
+		if err != nil {
+			logrus.Warnf("Wait io close timeout, some fifo io may be dropped.")
+		}
+
 		p.io.Close()
 	}
 	return &ExitStatus{code: r.ExitStatus, exitedAt: r.ExitedAt}, nil
-- 
2.27.0

