summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorMatthew Heon <mheon@redhat.com>2021-05-26 15:16:35 -0400
committerMatthew Heon <mheon@redhat.com>2021-05-26 15:33:28 -0400
commitfad6e1d3ef334076f180ab8a31ae7fa7a309e096 (patch)
treecb2f7ebf05340fdacc92d778338d525a67884853 /libpod
parentac94be37e996fdebf44e5ace83be5219b9488ec4 (diff)
downloadpodman-fad6e1d3ef334076f180ab8a31ae7fa7a309e096.tar.gz
podman-fad6e1d3ef334076f180ab8a31ae7fa7a309e096.tar.bz2
podman-fad6e1d3ef334076f180ab8a31ae7fa7a309e096.zip
Ensure that container still exists when removing
After #8906, there is a potential race condition in container removal of running containers with `--rm`. Running containers must first be stopped, which was changed to unlock the container to allow commands like `podman ps` to continue to run while stopping; however, this also means that the cleanup process can potentially run before we re-lock, and remove the container from under us, resulting in error messages from `podman rm`. The end result is unchanged, the container is still cleanly removed, but the `podman rm` command will seem to have failed. Work around this by pinging the database after we stop the container to make sure it still exists. If it doesn't, our job is done and we can exit cleanly. Signed-off-by: Matthew Heon <mheon@redhat.com>
Diffstat (limited to 'libpod')
-rw-r--r--libpod/runtime_ctr.go9
1 files changed, 9 insertions, 0 deletions
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 4e4b2a8ab..6c69d1b72 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -581,6 +581,15 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, remo
if err := c.stop(c.StopTimeout()); err != nil && errors.Cause(err) != define.ErrConmonDead {
return errors.Wrapf(err, "cannot remove container %s as it could not be stopped", c.ID())
}
+
+ // We unlocked as part of stop() above - there's a chance someone
+ // else got in and removed the container before we reacquired the
+ // lock.
+ // Do a quick ping of the database to check if the container
+ // still exists.
+ if ok, _ := r.state.HasContainer(c.ID()); !ok {
+ return nil
+ }
}
// Remove all active exec sessions