diff options
author | Valentin Rothberg <rothberg@redhat.com> | 2019-08-02 16:27:50 +0200 |
---|---|---|
committer | Valentin Rothberg <rothberg@redhat.com> | 2019-08-05 09:16:18 +0200 |
commit | 909ab594191ce964529398bcf7600edff9540d71 (patch) | |
tree | 84ff2ef873e80041c3854d1248f0b90264c4beaf /libpod/container_internal.go | |
parent | 389a7b79c295fc0477c22c571aef06934bf72219 (diff) | |
download | podman-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.go | 18 |
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 { |