Browse code

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 authored on 2014/07/12 03:22:01
Showing 3 changed files
... ...
@@ -50,6 +50,9 @@ func remote(eng *engine.Engine) error {
50 50
 // These components should be broken off into plugins of their own.
51 51
 //
52 52
 func daemon(eng *engine.Engine) error {
53
+	if err := eng.Register("initserverpidfile", server.InitPidfile); err != nil {
54
+		return err
55
+	}
53 56
 	if err := eng.Register("initserver", server.InitServer); err != nil {
54 57
 		return err
55 58
 	}
... ...
@@ -149,12 +149,22 @@ func main() {
149 149
 		if err := builtins.Register(eng); err != nil {
150 150
 			log.Fatal(err)
151 151
 		}
152
+
153
+		// handle the pidfile early. https://github.com/dotcloud/docker/issues/6973
154
+		if len(*pidfile) > 0 {
155
+			job := eng.Job("initserverpidfile", *pidfile)
156
+			if err := job.Run(); err != nil {
157
+				log.Fatal(err)
158
+			}
159
+		}
160
+
152 161
 		// load the daemon in the background so we can immediately start
153 162
 		// the http api so that connections don't fail while the daemon
154 163
 		// is booting
155 164
 		go func() {
156 165
 			// Load plugin: httpapi
157 166
 			job := eng.Job("initserver")
167
+			// include the variable here too, for the server config
158 168
 			job.Setenv("Pidfile", *pidfile)
159 169
 			job.Setenv("Root", realRoot)
160 170
 			job.SetenvBool("AutoRestart", *flAutoRestart)
... ...
@@ -72,6 +72,17 @@ func (srv *Server) handlerWrap(h engine.Handler) engine.Handler {
72 72
 	}
73 73
 }
74 74
 
75
+func InitPidfile(job *engine.Job) engine.Status {
76
+	if len(job.Args) == 0 {
77
+		return job.Error(fmt.Errorf("no pidfile provided to initialize"))
78
+	}
79
+	job.Logf("Creating pidfile")
80
+	if err := utils.CreatePidFile(job.Args[0]); err != nil {
81
+		return job.Error(err)
82
+	}
83
+	return engine.StatusOK
84
+}
85
+
75 86
 // jobInitApi runs the remote api server `srv` as a daemon,
76 87
 // Only one api server can run at the same time - this is enforced by a pidfile.
77 88
 // The signals SIGINT, SIGQUIT and SIGTERM are intercepted for cleanup.
... ...
@@ -81,13 +92,6 @@ func InitServer(job *engine.Job) engine.Status {
81 81
 	if err != nil {
82 82
 		return job.Error(err)
83 83
 	}
84
-	if srv.daemon.Config().Pidfile != "" {
85
-		job.Logf("Creating pidfile")
86
-		if err := utils.CreatePidFile(srv.daemon.Config().Pidfile); err != nil {
87
-			// FIXME: do we need fatal here instead of returning a job error?
88
-			log.Fatal(err)
89
-		}
90
-	}
91 84
 	job.Logf("Setting up signal traps")
92 85
 	c := make(chan os.Signal, 1)
93 86
 	gosignal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)