Skip to content

LXC state-aware exec timeout leaves script descendants running in the persistent container #867

Description

What

exec passes a timeout down to attach_run and nothing else:

src/backends/lxc/common/src/state_aware.rs:592-606

let timeout = if request.script_timeout == 0 { None }
              else { Some(Duration::from_millis(..)) };
let exit_code = container
    .attach_run(&request.script_code, .., timeout)

When that timeout fires, the attached process is torn down. Nothing in this
path reaps processes the script spawned inside the container. Because the
state-aware container is persistent -- it survives exec and lives until
deprovision -- those descendants keep running in it, and a later exec in the
same sandbox shares a container with them.

Why it matters

A timeout is the caller's statement that the work must not continue. Here it
ends the caller's view of the work while the work itself carries on, holding
CPU, memory, file handles, and network inside a container the caller believes is
idle. It also makes timeouts non-deterministic for anything that follows in the
same sandbox.

Fix

Reap the process tree on timeout rather than just the attached process -- kill
the container's PID namespace descendants, or stop and restart the container as
part of timeout handling. The right shape is worth designing rather than
patching, which is why this is an issue and not a change in PR #849.

Provenance -- reported twice

Verified still live: the code path above is unchanged from the version
Gudge (@MGudgin) reviewed. The descendant-survival mechanism is his, and it is
consistent with the code, which contains no reaping step at all.

Filing it so the second report does not share the fate of the first.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions