Skip to content

Commit

Permalink
Merge branch 'restarting-always' into 'IT-1.11.2'
Browse files Browse the repository at this point in the history
Fix Bug: canot remove restarting container

cherry pick from moby#25383

Signed-off-by: xiekeyang <xiekeyang@huawei.com>


See merge request docker/docker!206
  • Loading branch information
hqhq committed Dec 23, 2016
2 parents e52e5d4 + dc020f6 commit 2ad5f0f
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 34 deletions.
48 changes: 28 additions & 20 deletions libcontainerd/container_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,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,
Expand All @@ -144,42 +145,49 @@ 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
if err == nil {
if err = ctr.start(); err != nil {
logrus.Errorf("libcontainerd: error restarting %v", err)
}
}
if err != nil {
st.State = StateExit
ctr.clean()
ctr.client.q.append(e.Id, func() {
if err := ctr.client.backend.StateChanged(e.Id, st); err != nil {
logrus.Error(err)
logrus.Errorf("libcontainerd: %v", err)
}
})
if err != restartmanager.ErrRestartCanceled {
logrus.Error(err)
logrus.Errorf("libcontainerd: %v", err)
}
} else {
ctr.start()
}
}()
}
}

// 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.Error(err)
}
if e.Type == StatePause || e.Type == StateResume {
ctr.pauseMonitor.handle(e.Type)
}
Expand All @@ -191,7 +199,7 @@ func (ctr *container) handleEvent(e *containerd.Event) error {
})

default:
logrus.Debugf("event unhandled: %+v", e)
logrus.Debugf("libcontainerd: event unhandled: %+v", e)
}
return nil
}
Expand Down
34 changes: 20 additions & 14 deletions libcontainerd/container_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ func (ctr *container) start() error {
// equivalent to (in the linux containerd world) where events come in for
// state change notifications from containerd.
func (ctr *container) waitExit(pid uint32, processFriendlyName string, isFirstProcessToStart bool) error {
var waitRestart chan error
logrus.Debugln("waitExit on pid", pid)

// Block indefinitely for the process to exit.
Expand Down Expand Up @@ -181,19 +182,7 @@ func (ctr *container) waitExit(pid uint32, processFriendlyName string, isFirstPr
} else if restart {
si.State = StateRestart
ctr.restarting = true
go func() {
err := <-wait
ctr.restarting = false
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
}
}

Expand All @@ -209,7 +198,24 @@ func (ctr *container) waitExit(pid uint32, processFriendlyName string, isFirstPr
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 {
if err = ctr.client.Create(ctr.containerID, ctr.ociSpec, ctr.options...); err != nil {
logrus.Errorf("libcontainerd: error restarting %v", err)
}
}
if err != nil {
si.State = StateExit
if err := ctr.client.backend.StateChanged(ctr.containerID, si); err != nil {
logrus.Error(err)
}
}
}()
}
logrus.Debugln("waitExit() completed OK")
return nil
}

0 comments on commit 2ad5f0f

Please sign in to comment.