cleanup: add new --stopped-only option

The podman container cleanup process runs asynchronous and by the time
it gets the lock it is possible another podman process already did the
cleanup and then did a new init() to start it again. If the cleanup
process gets the lock there it will cause very weird things.

This can be observed in the remote start API as CI flakes.

Fixes #23754

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger
2024-08-27 14:54:31 +02:00
parent bf74797c69
commit a89fef6e2a
6 changed files with 20 additions and 7 deletions

View File

@ -785,8 +785,10 @@ func (c *Container) WaitForConditionWithInterval(ctx context.Context, waitTimeou
}
// Cleanup unmounts all mount points in container and cleans up container storage
// It also cleans up the network stack
func (c *Container) Cleanup(ctx context.Context) error {
// It also cleans up the network stack.
// onlyStopped is set by the podman container cleanup to ensure we only cleanup a stopped container,
// all other states mean another process already called cleanup before us which is fine in such cases.
func (c *Container) Cleanup(ctx context.Context, onlyStopped bool) error {
if !c.batched {
c.lock.Lock()
defer c.lock.Unlock()
@ -808,6 +810,9 @@ func (c *Container) Cleanup(ctx context.Context) error {
if !c.ensureState(define.ContainerStateConfigured, define.ContainerStateCreated, define.ContainerStateStopped, define.ContainerStateStopping, define.ContainerStateExited) {
return fmt.Errorf("container %s is running or paused, refusing to clean up: %w", c.ID(), define.ErrCtrStateInvalid)
}
if onlyStopped && !c.ensureState(define.ContainerStateStopped) {
return fmt.Errorf("container %s is not stopped and only cleanup for a stopped container was requested: %w", c.ID(), define.ErrCtrStateInvalid)
}
// if the container was not created in the oci runtime or was already cleaned up, then do nothing
if c.ensureState(define.ContainerStateConfigured, define.ContainerStateExited) {