82 lines
2.8 KiB
Diff
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
|
|
|