浏览代码

docker daemon: initialize the daemon pidfile early

fixes https://github.com/dotcloud/docker/issues/6973

Docker-DCO-1.1-Signed-off-by: Vincent Batts <vbatts@redhat.com> (github: vbatts)
Vincent Batts 11 年之前
父节点
当前提交
848e837698
共有 3 个文件被更改,包括 24 次插入7 次删除
  1. 3 0
      builtins/builtins.go
  2. 10 0
      docker/docker.go
  3. 11 7
      server/server.go

+ 3 - 0
builtins/builtins.go

@@ -50,6 +50,9 @@ func remote(eng *engine.Engine) error {
 // These components should be broken off into plugins of their own.
 // These components should be broken off into plugins of their own.
 //
 //
 func daemon(eng *engine.Engine) error {
 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 {
 	if err := eng.Register("initserver", server.InitServer); err != nil {
 		return err
 		return err
 	}
 	}

+ 10 - 0
docker/docker.go

@@ -149,12 +149,22 @@ func main() {
 		if err := builtins.Register(eng); err != nil {
 		if err := builtins.Register(eng); err != nil {
 			log.Fatal(err)
 			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
 		// load the daemon in the background so we can immediately start
 		// the http api so that connections don't fail while the daemon
 		// the http api so that connections don't fail while the daemon
 		// is booting
 		// is booting
 		go func() {
 		go func() {
 			// Load plugin: httpapi
 			// Load plugin: httpapi
 			job := eng.Job("initserver")
 			job := eng.Job("initserver")
+			// include the variable here too, for the server config
 			job.Setenv("Pidfile", *pidfile)
 			job.Setenv("Pidfile", *pidfile)
 			job.Setenv("Root", realRoot)
 			job.Setenv("Root", realRoot)
 			job.SetenvBool("AutoRestart", *flAutoRestart)
 			job.SetenvBool("AutoRestart", *flAutoRestart)

+ 11 - 7
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,
 // 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.
 // 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.
 // The signals SIGINT, SIGQUIT and SIGTERM are intercepted for cleanup.
@@ -81,13 +92,6 @@ func InitServer(job *engine.Job) engine.Status {
 	if err != nil {
 	if err != nil {
 		return job.Error(err)
 		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")
 	job.Logf("Setting up signal traps")
 	c := make(chan os.Signal, 1)
 	c := make(chan os.Signal, 1)
 	gosignal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
 	gosignal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)