pub fn agent_running(pid: u32) -> boolExpand description
Check whether a process with the given PID is still running.
The PID typically comes from parsing an on-disk file, so hostile or
corrupted values must be rejected, not reinterpreted: kill(0, sig)
signals the caller’s own process group (a “0” PID file would read as
permanently alive), and a value above i32::MAX would wrap negative
through an as libc::pid_t cast — kill(-1, 0) probes every process
the caller may signal and virtually always succeeds.
Zombies are NOT running. kill(pid, 0) succeeds for a process that
has exited but not yet been reaped: the pid stays allocated until its
parent calls wait, so the bare POSIX check reports a dead agent as
alive. That is not academic here — when a monitor dies before its agent,
the agent reparents to PID 1, and inside a container PID 1 is whatever
the image runs (cargo, a shell, the test harness), none of which reap
orphans the way an init system does. The zombie then persists for the
life of the container and every liveness check keeps answering “yes”.
That is exactly the “monitor over-durability” class Phase 23 exists to
close: an operator, gate sweep, or stop asking “is this phase still
running?” would be told yes forever about a process that is already dead.
Observed directly in CI (sigterm_to_monitor_also_kills_the_agent), where
both monitor and agent were State=Z and the agent had reparented to
PPid=1 while the bare check still reported them alive.
Reading /proc is Linux-only; where it cannot be read, this falls back to
the kill(0) answer rather than inventing one.