diff --git a/libcontainerd/container_linux.go b/libcontainerd/container_linux.go index d6bfc22364..00129e5851 100644 --- a/libcontainerd/container_linux.go +++ b/libcontainerd/container_linux.go @@ -144,6 +144,7 @@ func (ctr *container) handleEvent(e *containerd.Event) error { defer ctr.client.unlock(ctr.containerID) switch e.Type { case StateExit, StatePause, StateResume, StateOOM: + var waitRestart chan error st := StateInfo{ CommonStateInfo: CommonStateInfo{ State: e.Type, @@ -166,8 +167,26 @@ func (ctr *container) handleEvent(e *containerd.Event) error { st.State = StateRestart ctr.restarting = true ctr.client.deleteContainer(e.Id) + waitRestart = wait + } + } + + // Remove process from list if we have exited + // We need to do so here in case the Message Handler decides to restart it. + switch st.State { + case StateExit: + ctr.clean() + ctr.client.deleteContainer(e.Id) + case StateExitProcess: + ctr.cleanProcess(st.ProcessID) + } + ctr.client.q.append(e.Id, func() { + if err := ctr.client.backend.StateChanged(e.Id, st); err != nil { + logrus.Errorf("libcontainerd: backend.StateChanged(): %v", err) + } + if st.State == StateRestart { go func() { - err := <-wait + err := <-waitRestart ctr.client.lock(ctr.containerID) defer ctr.client.unlock(ctr.containerID) ctr.restarting = false @@ -187,21 +206,7 @@ func (ctr *container) handleEvent(e *containerd.Event) error { } }() } - } - // Remove process from list if we have exited - // We need to do so here in case the Message Handler decides to restart it. - switch st.State { - case StateExit: - ctr.clean() - ctr.client.deleteContainer(e.Id) - case StateExitProcess: - ctr.cleanProcess(st.ProcessID) - } - ctr.client.q.append(e.Id, func() { - if err := ctr.client.backend.StateChanged(e.Id, st); err != nil { - logrus.Errorf("libcontainerd: backend.StateChanged(): %v", err) - } if e.Type == StatePause || e.Type == StateResume { ctr.pauseMonitor.handle(e.Type) } diff --git a/libcontainerd/container_windows.go b/libcontainerd/container_windows.go index 8e5328941f..4cd18c784b 100644 --- a/libcontainerd/container_windows.go +++ b/libcontainerd/container_windows.go @@ -195,6 +195,7 @@ func (ctr *container) waitProcessExitCode(process *process) int { // equivalent to (in the linux containerd world) where events come in for // state change notifications from containerd. func (ctr *container) waitExit(process *process, isFirstProcessToStart bool) error { + var waitRestart chan error logrus.Debugln("libcontainerd: waitExit() on pid", process.systemPid) exitCode := ctr.waitProcessExitCode(process) @@ -238,20 +239,7 @@ func (ctr *container) waitExit(process *process, isFirstProcessToStart bool) err } else if restart { si.State = StateRestart ctr.restarting = true - go func() { - err := <-wait - ctr.restarting = false - ctr.client.deleteContainer(ctr.friendlyName) - if err != nil { - si.State = StateExit - if err := ctr.client.backend.StateChanged(ctr.containerID, si); err != nil { - logrus.Error(err) - } - logrus.Error(err) - } else { - ctr.client.Create(ctr.containerID, ctr.ociSpec, ctr.options...) - } - }() + waitRestart = wait } } @@ -267,6 +255,22 @@ func (ctr *container) waitExit(process *process, isFirstProcessToStart bool) err if err := ctr.client.backend.StateChanged(ctr.containerID, si); err != nil { logrus.Error(err) } + if si.State == StateRestart { + go func() { + err := <-waitRestart + ctr.restarting = false + ctr.client.deleteContainer(ctr.friendlyName) + if err != nil { + si.State = StateExit + if err := ctr.client.backend.StateChanged(ctr.containerID, si); err != nil { + logrus.Error(err) + } + logrus.Error(err) + } else { + ctr.client.Create(ctr.containerID, ctr.ociSpec, ctr.options...) + } + }() + } logrus.Debugf("libcontainerd: waitExit() completed OK, %+v", si) return nil