summaryrefslogtreecommitdiff
path: root/libpod/container_internal.go
diff options
context:
space:
mode:
authorValentin Rothberg <rothberg@redhat.com>2019-08-02 16:27:50 +0200
committerValentin Rothberg <rothberg@redhat.com>2019-08-05 09:16:18 +0200
commit909ab594191ce964529398bcf7600edff9540d71 (patch)
tree84ff2ef873e80041c3854d1248f0b90264c4beaf /libpod/container_internal.go
parent389a7b79c295fc0477c22c571aef06934bf72219 (diff)
downloadpodman-909ab594191ce964529398bcf7600edff9540d71.tar.gz
podman-909ab594191ce964529398bcf7600edff9540d71.tar.bz2
podman-909ab594191ce964529398bcf7600edff9540d71.zip
container stop: kill conmon
Old versions of conmon have a bug where they create the exit file before closing open file descriptors causing a race condition when restarting containers with open ports since we cannot bind the ports as they're not yet closed by conmon. Killing the old conmon PID is ~okay since it forces the FDs of old conmons to be closed, while it's a NOP for newer versions which should have exited already. Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
Diffstat (limited to 'libpod/container_internal.go')
-rw-r--r--libpod/container_internal.go18
1 files changed, 18 insertions, 0 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index aba9c5b93..313f67963 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -1152,9 +1152,27 @@ func (c *Container) restartWithTimeout(ctx context.Context, timeout uint) (err e
c.newContainerEvent(events.Restart)
if c.state.State == define.ContainerStateRunning {
+ conmonPID := c.state.ConmonPID
if err := c.stop(timeout); err != nil {
return err
}
+ // Old versions of conmon have a bug where they create the exit file before
+ // closing open file descriptors causing a race condition when restarting
+ // containers with open ports since we cannot bind the ports as they're not
+ // yet closed by conmon.
+ //
+ // Killing the old conmon PID is ~okay since it forces the FDs of old conmons
+ // to be closed, while it's a NOP for newer versions which should have
+ // exited already.
+ if conmonPID != 0 {
+ // Ignore errors from FindProcess() as conmon could already have exited.
+ p, err := os.FindProcess(conmonPID)
+ if p != nil && err == nil {
+ if err = p.Kill(); err != nil {
+ logrus.Debugf("error killing conmon process: %v", err)
+ }
+ }
+ }
}
defer func() {
if err != nil {