From 848e837698922fed0fa67930aa0b56a96b1b832d Mon Sep 17 00:00:00 2001 From: Vincent Batts Date: Fri, 11 Jul 2014 14:22:01 -0400 Subject: [PATCH] docker daemon: initialize the daemon pidfile early fixes https://github.com/dotcloud/docker/issues/6973 Docker-DCO-1.1-Signed-off-by: Vincent Batts (github: vbatts) --- builtins/builtins.go | 3 +++ docker/docker.go | 10 ++++++++++ server/server.go | 18 +++++++++++------- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/builtins/builtins.go b/builtins/builtins.go index 3fa06510d0..bac130c8df 100644 --- a/builtins/builtins.go +++ b/builtins/builtins.go @@ -50,6 +50,9 @@ func remote(eng *engine.Engine) error { // These components should be broken off into plugins of their own. // func daemon(eng *engine.Engine) error { + if err := eng.Register("initserverpidfile", server.InitPidfile); err != nil { + return err + } if err := eng.Register("initserver", server.InitServer); err != nil { return err } diff --git a/docker/docker.go b/docker/docker.go index e21d0a4d70..d0a2ea33af 100644 --- a/docker/docker.go +++ b/docker/docker.go @@ -149,12 +149,22 @@ func main() { if err := builtins.Register(eng); err != nil { log.Fatal(err) } + + // handle the pidfile early. https://github.com/dotcloud/docker/issues/6973 + if len(*pidfile) > 0 { + job := eng.Job("initserverpidfile", *pidfile) + if err := job.Run(); err != nil { + log.Fatal(err) + } + } + // load the daemon in the background so we can immediately start // the http api so that connections don't fail while the daemon // is booting go func() { // Load plugin: httpapi job := eng.Job("initserver") + // include the variable here too, for the server config job.Setenv("Pidfile", *pidfile) job.Setenv("Root", realRoot) job.SetenvBool("AutoRestart", *flAutoRestart) diff --git a/server/server.go b/server/server.go index 40995da5c4..6cabdc34c2 100644 --- a/server/server.go +++ b/server/server.go @@ -72,6 +72,17 @@ func (srv *Server) handlerWrap(h engine.Handler) engine.Handler { } } +func InitPidfile(job *engine.Job) engine.Status { + if len(job.Args) == 0 { + return job.Error(fmt.Errorf("no pidfile provided to initialize")) + } + job.Logf("Creating pidfile") + if err := utils.CreatePidFile(job.Args[0]); err != nil { + return job.Error(err) + } + return engine.StatusOK +} + // jobInitApi runs the remote api server `srv` as a daemon, // Only one api server can run at the same time - this is enforced by a pidfile. // The signals SIGINT, SIGQUIT and SIGTERM are intercepted for cleanup. @@ -81,13 +92,6 @@ func InitServer(job *engine.Job) engine.Status { if err != nil { return job.Error(err) } - if srv.daemon.Config().Pidfile != "" { - job.Logf("Creating pidfile") - if err := utils.CreatePidFile(srv.daemon.Config().Pidfile); err != nil { - // FIXME: do we need fatal here instead of returning a job error? - log.Fatal(err) - } - } job.Logf("Setting up signal traps") c := make(chan os.Signal, 1) gosignal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)