docker/patch/0198-docker-fix-docker-kill-command-block.patch
2022-06-28 16:29:12 +08:00

82 lines
2.8 KiB
Diff

From 74bd1d0c00c53f96696663e45507e332684dac7a Mon Sep 17 00:00:00 2001
From: xiadanni <xiadanni1@huawei.com>
Date: Wed, 3 Mar 2021 16:46:50 +0800
Subject: [PATCH] docker: fix docker kill command block
reason:When docker kill command execute with start/restart command
concurrently, kill command may block at <-container.Wait.
As s.waitStop is variable, so there is case that waitStop in Wait
function get a new s.waitStop(the old one is already closed before).
So kill command blocked to wait the new s.waitStop close.
Signed-off-by: xiadanni <xiadanni1@huawei.com>
---
components/engine/container/state.go | 13 +++++++++++--
components/engine/daemon/kill.go | 4 +++-
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/components/engine/container/state.go b/components/engine/container/state.go
index 91ea30a..e9666ed 100644
--- a/components/engine/container/state.go
+++ b/components/engine/container/state.go
@@ -65,6 +65,10 @@ func NewState() *State {
}
}
+func (s State) GetWaitStop() chan struct{} {
+ return s.waitStop
+}
+
// String returns a human-readable description of the state
func (s *State) String() string {
if s.Running {
@@ -179,6 +183,10 @@ const (
// otherwise, the results Err() method will return an error indicating why the
// wait operation failed.
func (s *State) Wait(ctx context.Context, condition WaitCondition) <-chan StateStatus {
+ return s.Wait3(ctx, condition, nil)
+}
+
+func (s *State) Wait3(ctx context.Context, condition WaitCondition, waitStop chan struct{}) <-chan StateStatus {
s.Lock()
defer s.Unlock()
@@ -197,9 +205,10 @@ func (s *State) Wait(ctx context.Context, condition WaitCondition) <-chan StateS
// If we are waiting only for removal, the waitStop channel should
// remain nil and block forever.
- var waitStop chan struct{}
if condition < WaitConditionRemoved {
- waitStop = s.waitStop
+ if waitStop == nil {
+ waitStop = s.waitStop
+ }
}
// Always wait for removal, just in case the container gets removed
diff --git a/components/engine/daemon/kill.go b/components/engine/daemon/kill.go
index d185065..4c8ccf9 100644
--- a/components/engine/daemon/kill.go
+++ b/components/engine/daemon/kill.go
@@ -132,6 +132,8 @@ func (daemon *Daemon) Kill(container *containerpkg.Container) error {
return nil
}
+ waitStop := container.GetWaitStop()
+
// 1. Send SIGKILL
if err := daemon.killPossiblyDeadProcess(container, int(syscall.SIGKILL)); err != nil {
// While normally we might "return err" here we're not going to
@@ -166,7 +168,7 @@ func (daemon *Daemon) Kill(container *containerpkg.Container) error {
// Wait for exit with no timeout.
// Ignore returned status.
- <-container.Wait(context.Background(), containerpkg.WaitConditionNotRunning)
+ <-container.Wait3(context.Background(), containerpkg.WaitConditionNotRunning, waitStop)
return nil
}
--
1.8.3.1