Skip to content

Commit

Permalink
Fix: Prevent OCI runtime directory remain
Browse files Browse the repository at this point in the history
This bug was introduced in containers#8906.

When we use 'podman rm/restart/stop/kill etc...' command to
the container running with --rm, the OCI runtime directory
remains at /run/<runtime name> (root user) or
/run/user/<user id>/<runtime name> (rootless user).

This bug could cause other bugs.
For example, when we checkpoint the container running with
--rm (podman checkpoint --export) and restore it
(podman restore --import) with crun, error message
"Error: OCI runtime error: crun: container `<container id>`
already exists" is outputted.
This error is caused by an attempt to restore the container with
the same container ID as the remaining OCI runtime's container ID.

Therefore, I fix that the cleanupRuntime() function runs to
remove the OCI runtime directory,
even if the container has already been removed by --rm option.

Signed-off-by: Toshiki Sonoda <[email protected]>
  • Loading branch information
sstosh committed Jun 24, 2022
1 parent 8e88abd commit 3619f0b
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 1 deletion.
9 changes: 9 additions & 0 deletions libpod/container_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,15 @@ func (c *Container) Cleanup(ctx context.Context) error {
defer c.lock.Unlock()

if err := c.syncContainer(); err != nil {
switch errors.Cause(err) {
// When the container has already been removed, the OCI runtime directory remain.
case define.ErrNoSuchCtr, define.ErrCtrRemoved:
if err := c.cleanupRuntime(ctx); err != nil {
return errors.Wrapf(err, "error cleaning up container %s from OCI runtime", c.ID())
}
default:
logrus.Errorf("Syncing container %s status: %v", c.ID(), err)
}
return err
}
}
Expand Down
3 changes: 2 additions & 1 deletion libpod/container_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -1309,8 +1309,9 @@ func (c *Container) stop(timeout uint) error {
if err := c.syncContainer(); err != nil {
switch errors.Cause(err) {
// If the container has already been removed (e.g., via
// the cleanup process), there's nothing left to do.
// the cleanup process), set the container state to "stopped".
case define.ErrNoSuchCtr, define.ErrCtrRemoved:
c.state.State = define.ContainerStateStopped
return stopErr
default:
if stopErr != nil {
Expand Down
4 changes: 4 additions & 0 deletions libpod/runtime_ctr.go
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,10 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, remo
// Do a quick ping of the database to check if the container
// still exists.
if ok, _ := r.state.HasContainer(c.ID()); !ok {
// When the container has already been removed, the OCI runtime directory remain.
if err := c.cleanupRuntime(ctx); err != nil {
return errors.Wrapf(err, "error cleaning up container %s from OCI runtime", c.ID())
}
return nil
}
}
Expand Down
15 changes: 15 additions & 0 deletions test/system/050-stop.bats
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,19 @@ load helpers
run_podman --noout stop -t 0 stopme
is "$output" "" "output should be empty"
}

@test "podman stop, with --rm container" {
OCIDir=/run/$(podman_runtime)

if is_rootless; then
OCIDir=/run/user/$(id -u)/$(podman_runtime)
fi

run_podman run --rm -d --name rmstop $IMAGE sleep infinity
local cid="$output"
run_podman stop rmstop

# Check the OCI runtime directory has removed.
is "$(ls $OCIDir | grep $cid)" "" "The OCI runtime directory should have been removed"
}
# vim: filetype=sh
10 changes: 10 additions & 0 deletions test/system/055-rm.bats
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,20 @@ load helpers
}

@test "podman rm <-> run --rm race" {
OCIDir=/run/$(podman_runtime)

if is_rootless; then
OCIDir=/run/user/$(id -u)/$(podman_runtime)
fi

# A container's lock is released before attempting to stop it. This opens
# the window for race conditions that led to #9479.
run_podman run --rm -d $IMAGE sleep infinity
local cid="$output"
run_podman rm -af

# Check the OCI runtime directory has removed.
is "$(ls $OCIDir | grep $cid)" "" "The OCI runtime directory should have been removed"
}

@test "podman rm --depend" {
Expand Down

0 comments on commit 3619f0b

Please sign in to comment.