Expand description
Linux tracker: one cgroup v2 per agent, under a systemd user scope srv
puts itself in at startup with Delegate=yes, so srv may create and
manage cgroups below it.
A cgroup holds every descendant of what it was given, whatever they do:
setsid, double forks and reparenting don’t leave it (process groups and
sessions can’t hold an agent’s tree: Claude Code and bashwrap each start
new sessions). cgroup.kill ends all of them at once.
See docs/analysis/agent-spawned-process-tracking-2026-10-07.md.
Structs§
- Cgroup
Tracker - One agent’s cgroup.
Constants§
Statics§
- ROOT 🔒
- srv’s delegated scope directory, or
Nonewhen it couldn’t get one (no cgroup v2, no systemd user manager): trackers then fall back.
Functions§
- init
- Move srv into its own delegated systemd user scope
(
agentmux-srv-<pid>.scope). Call once at startup, before any agent spawns. Idempotent; never fails startup. - join_
before_ exec - Make a child join
procs(acgroup.procsfile) before it execs, so it is tracked before it runs any code of its own and before it can fork. - join_
before_ exec_ pty join_before_execfor a PTY spawn (portable-pty has no pre-exec hook): run the command throughsh, which joins and thenexecs it, so the program starts already in the cgroup, as the same process.- kill_
all 🔒 - Kill everything in
dir:cgroup.kill(kernel 5.14+), else SIGKILL each member until none is left. - own_
cgroup 🔒 - This process’s cgroup v2 path (
/user.slice/…). - pids_in 🔒
- populated 🔒
- root
- The directory per-agent cgroups are created in, once
initsucceeded. - setup 🔒
- signal 🔒
- start_
transient_ 🔒scope - Ask the user’s systemd manager for a transient scope holding this
process, delegated to us (what
systemd-run --user --scope -p Delegate=yesdoes). - usage_
usec 🔒 usage_usecfrom acpu.stat.