From 3b3f4bf052e442543ec5772875ce7fbc77924596 Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" <guillaume@charmes.net> Date: Wed, 2 Apr 2014 05:56:11 -0700 Subject: [PATCH 1/2] Return correct exit code upon signal + SIGQUIT now quits without cleanup Docker-DCO-1.1-Signed-off-by: Guillaume J. Charmes <guillaume@charmes.net> (github: creack) --- server/server.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/server/server.go b/server/server.go index 1c6c561375..d6fa7a0c2a 100644 --- a/server/server.go +++ b/server/server.go @@ -54,11 +54,16 @@ func InitServer(job *engine.Job) engine.Status { c := make(chan os.Signal, 1) gosignal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT) go func() { - sig := <-c - log.Printf("Received signal '%v', starting shutdown of docker...\n", sig) - utils.RemovePidFile(srv.runtime.Config().Pidfile) - srv.Close() - os.Exit(0) + for sig := range c { + log.Printf("Received signal '%v', starting shutdown of docker...\n", sig) + switch sig { + case os.Interrupt, syscall.SIGTERM: + utils.RemovePidFile(srv.runtime.Config().Pidfile) + srv.Close() + case syscall.SIGQUIT: + } + os.Exit(128 + int(sig.(syscall.Signal))) + } }() job.Eng.Hack_SetGlobalVar("httpapi.server", srv) job.Eng.Hack_SetGlobalVar("httpapi.runtime", srv.runtime) From cd910cb6858541b432e20b650fad262772c9ef18 Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" <guillaume@charmes.net> Date: Wed, 2 Apr 2014 18:00:13 -0700 Subject: [PATCH 2/2] Allow force sigint and allow sigquit after sigint Docker-DCO-1.1-Signed-off-by: Guillaume J. Charmes <guillaume@charmes.net> (github: creack) --- server/server.go | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/server/server.go b/server/server.go index d6fa7a0c2a..fae50094c2 100644 --- a/server/server.go +++ b/server/server.go @@ -54,15 +54,29 @@ func InitServer(job *engine.Job) engine.Status { c := make(chan os.Signal, 1) gosignal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT) go func() { + interruptCount := 0 for sig := range c { - log.Printf("Received signal '%v', starting shutdown of docker...\n", sig) - switch sig { - case os.Interrupt, syscall.SIGTERM: - utils.RemovePidFile(srv.runtime.Config().Pidfile) - srv.Close() - case syscall.SIGQUIT: - } - os.Exit(128 + int(sig.(syscall.Signal))) + go func() { + log.Printf("Received signal '%v', starting shutdown of docker...\n", sig) + switch sig { + case os.Interrupt, syscall.SIGTERM: + // If the user really wants to interrupt, let him do so. + if interruptCount < 3 { + interruptCount++ + // Initiate the cleanup only once + if interruptCount == 1 { + utils.RemovePidFile(srv.runtime.Config().Pidfile) + srv.Close() + } else { + return + } + } else { + log.Printf("Force shutdown of docker, interrupting cleanup\n") + } + case syscall.SIGQUIT: + } + os.Exit(128 + int(sig.(syscall.Signal))) + }() } }() job.Eng.Hack_SetGlobalVar("httpapi.server", srv)