diff options
author | Giuseppe Scrivano <gscrivan@redhat.com> | 2022-04-29 12:02:00 +0200 |
---|---|---|
committer | Giuseppe Scrivano <gscrivan@redhat.com> | 2022-04-29 12:58:11 +0200 |
commit | 384c2359b7adf9441e949128d58396872b30fc84 (patch) | |
tree | 604efbb265284bda61530727ec23089272bc8f0d | |
parent | ab3e072a0c3d321fd12cbd1f6ef8e322c6d9214a (diff) | |
download | podman-384c2359b7adf9441e949128d58396872b30fc84.tar.gz podman-384c2359b7adf9441e949128d58396872b30fc84.tar.bz2 podman-384c2359b7adf9441e949128d58396872b30fc84.zip |
libpod: unlock containers when removing pod
It solves a race where a container cleanup process launched because of
the container process exiting normally would hang.
It also solves a problem when running as rootless on cgroup v1 since
it is not possible to force pids.max = 1 on conmon to limit spawning
the cleanup process.
Partially copied from https://github.com/containers/podman/pull/13403
Related to: https://github.com/containers/podman/issues/14057
[NO NEW TESTS NEEDED] it doesn't add any new functionality
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
-rw-r--r-- | libpod/runtime_pod_linux.go | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/libpod/runtime_pod_linux.go b/libpod/runtime_pod_linux.go index 2bbccfdf6..62ec7df60 100644 --- a/libpod/runtime_pod_linux.go +++ b/libpod/runtime_pod_linux.go @@ -199,10 +199,15 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool, // Go through and lock all containers so we can operate on them all at // once. // First loop also checks that we are ready to go ahead and remove. + containersLocked := true for _, ctr := range ctrs { ctrLock := ctr.lock ctrLock.Lock() - defer ctrLock.Unlock() + defer func() { + if containersLocked { + ctrLock.Unlock() + } + }() // If we're force-removing, no need to check status. if force { @@ -304,6 +309,12 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool, } } + // let's unlock the containers so if there is any cleanup process, it can terminate its execution + for _, ctr := range ctrs { + ctr.lock.Unlock() + } + containersLocked = false + // Remove pod cgroup, if present if p.state.CgroupPath != "" { logrus.Debugf("Removing pod cgroup %s", p.state.CgroupPath) @@ -332,7 +343,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool, } } if err == nil { - if err := conmonCgroup.Delete(); err != nil { + if err = conmonCgroup.Delete(); err != nil { if removalErr == nil { removalErr = errors.Wrapf(err, "error removing pod %s conmon cgroup", p.ID()) } else { |