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>
| ... | ... |
@@ -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 |
|