containerd/patch/0038-containerd-add-timeout-for-I-O-waitgroups.patch
Grooooot 3a981f1909 containerd:add patches
Signed-off-by: Grooooot <isula@huawei.com>
2020-03-05 15:54:34 +08:00

90 lines
2.7 KiB
Diff

From d886f6c03cca051b45fd77cc77d0cc870aed1aed Mon Sep 17 00:00:00 2001
From: build <build@obs.com>
Date: Wed, 4 Sep 2019 05:21:06 -0400
Subject: [PATCH] containerd: add timeout for I/O waitgroups
reason: This and a combination of a couple Docker changes are needed to fully
resolve the issue on the Docker side. However, this ensures that after
processes exit, we still leave some time for the I/O to fully flush
before closing. Without this timeout, the delete methods would block
forever.
Cherry-pick from upstream 245052243d
Reference from https://github.com/containerd/containerd/pull/3361
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
---
runtime/v1/linux/proc/exec.go | 2 +-
runtime/v1/linux/proc/init.go | 2 +-
runtime/v1/linux/proc/utils.go | 20 ++++++++++++++++++++
3 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/runtime/v1/linux/proc/exec.go b/runtime/v1/linux/proc/exec.go
index 715a977..08c581f 100644
--- a/runtime/v1/linux/proc/exec.go
+++ b/runtime/v1/linux/proc/exec.go
@@ -94,7 +94,7 @@ func (e *execProcess) setExited(status int) {
}
func (e *execProcess) delete(ctx context.Context) error {
- e.wg.Wait()
+ waitTimeout(ctx, &e.wg, 2*time.Second)
if e.io != nil {
for _, c := range e.closers {
c.Close()
diff --git a/runtime/v1/linux/proc/init.go b/runtime/v1/linux/proc/init.go
index 44d3f58..49fa8ec 100644
--- a/runtime/v1/linux/proc/init.go
+++ b/runtime/v1/linux/proc/init.go
@@ -263,7 +263,7 @@ func (p *Init) setExited(status int) {
}
func (p *Init) delete(context context.Context) error {
- p.wg.Wait()
+ waitTimeout(context, &p.wg, 2*time.Second)
err := p.runtime.Delete(context, p.id, nil)
// ignore errors if a runtime has already deleted the process
// but we still hold metadata and pipes
diff --git a/runtime/v1/linux/proc/utils.go b/runtime/v1/linux/proc/utils.go
index ab9f5fa..d6f047c 100644
--- a/runtime/v1/linux/proc/utils.go
+++ b/runtime/v1/linux/proc/utils.go
@@ -19,10 +19,12 @@
package proc
import (
+ "context"
"encoding/json"
"io"
"os"
"strings"
+ "sync"
"time"
"github.com/containerd/containerd/errdefs"
@@ -103,3 +105,21 @@ func checkKillError(err error) error {
func hasNoIO(r *CreateConfig) bool {
return r.Stdin == "" && r.Stdout == "" && r.Stderr == ""
}
+
+// waitTimeout handles waiting on a waitgroup with a specified timeout.
+// this is commonly used for waiting on IO to finish after a process has exited
+func waitTimeout(ctx context.Context, wg *sync.WaitGroup, timeout time.Duration) error {
+ ctx, cancel := context.WithTimeout(ctx, timeout)
+ defer cancel()
+ done := make(chan struct{}, 1)
+ go func() {
+ wg.Wait()
+ close(done)
+ }()
+ select {
+ case <-done:
+ return nil
+ case <-ctx.Done():
+ return ctx.Err()
+ }
+}
--
2.20.1