From 5eb7f017e1641f1eef741e41d585462a84d783b2 Mon Sep 17 00:00:00 2001 From: mingfukuang Date: Fri, 19 Jul 2019 04:37:31 -0400 Subject: [PATCH] docker-proxy cannot exit after send SIGINT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: mingfukuang When stop or delete one container with docker-proxy, stop container will call Unmap() to release port , func Unmap() need to acquire pm.lock.Lock() firstly, then stop docker-proxy, and then pm.lock.UnLock(). but some situation(cannot be reproduced), stop docker-proxy will hang on. Once one container cann't stop docker-proxy, above mentioned pm.lock cann't be released, so this container cann’t be stopped, Also all operation of this container could be hang on. Furthermore, if other containers enter stop or delete process, those containers also need to acquire the global pm.lock, and get stuck. As result, other operations to those containers also hang on, such as docker inspect, docker exec, etc. To fix this, I add protective measures to avoid the situation of global lock(pm.lock)cann't being released. --- portmapper/proxy.go | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/portmapper/proxy.go b/portmapper/proxy.go index 12e4122c05..9d3d5f6531 100644 --- a/portmapper/proxy.go +++ b/portmapper/proxy.go @@ -7,6 +7,7 @@ import ( "net" "os" "os/exec" + "syscall" "time" "github.com/ishidawataru/sctp" @@ -65,10 +66,26 @@ func (p *proxyCommand) Start() error { func (p *proxyCommand) Stop() error { if p.cmd.Process != nil { - if err := p.cmd.Process.Signal(os.Interrupt); err != nil { + if err := p.cmd.Process.Signal(syscall.SIGTERM); err != nil { return err } - return p.cmd.Wait() + + waitChan := make(chan error) + go func() { + waitChan <- p.cmd.Wait() + }() + + t := time.NewTimer(15 * time.Second) + defer t.Stop() + + select { + case result := <-waitChan: + return result + case <-t.C: + if err := p.cmd.Process.Signal(os.Kill); err != nil { + return err + } + } } return nil }