Browse code

Fix race in container creation

Only register a container once it's successfully started. This avoids a
race condition where the daemon is killed while in the process of
calling `libcontainer.Container.Start`, and ends up killing -1.

There is a time window where the container `initProcess` is not set, and
its PID unknown. This commit fixes the race Engine side.

Signed-off-by: Arnaud Porterie <arnaud.porterie@docker.com>

Arnaud Porterie authored on 2016/03/04 12:42:54
Showing 1 changed files
... ...
@@ -157,6 +157,10 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd
157 157
 	if err != nil {
158 158
 		return execdriver.ExitStatus{ExitCode: -1}, err
159 159
 	}
160
+
161
+	if err := cont.Start(p); err != nil {
162
+		return execdriver.ExitStatus{ExitCode: -1}, err
163
+	}
160 164
 	d.Lock()
161 165
 	d.activeContainers[c.ID] = cont
162 166
 	d.Unlock()
... ...
@@ -167,10 +171,6 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd
167 167
 		d.cleanContainer(c.ID)
168 168
 	}()
169 169
 
170
-	if err := cont.Start(p); err != nil {
171
-		return execdriver.ExitStatus{ExitCode: -1}, err
172
-	}
173
-
174 170
 	//close the write end of any opened pipes now that they are dup'ed into the container
175 171
 	for _, writer := range writers {
176 172
 		writer.Close()
... ...
@@ -302,6 +302,9 @@ func (d *Driver) Kill(c *execdriver.Command, sig int) error {
302 302
 	if err != nil {
303 303
 		return err
304 304
 	}
305
+	if state.InitProcessPid == -1 {
306
+		return fmt.Errorf("avoid sending signal %d to container %s with pid -1", sig, c.ID)
307
+	}
305 308
 	return syscall.Kill(state.InitProcessPid, syscall.Signal(sig))
306 309
 }
307 310