Summary
On macOS, fs_usage reads the kernel trace facility (kdebug), which is effectively a single global, single-consumer resource (shared with dtrace, latency, sc_usage). When two Thumper agents run on the same host and both take the fs_usage path in watch_fs_usage, only one can hold the trace. The agent that starts fs_usage last wins, and the earlier agent's fs_usage is terminated — silently disabling its read detection.
Evidence (observed live)
Two agents on one Mac, both root, byte-identical thumper_agent.sh:
thumper-demo (/usr/local/thumper) — started 11:17 — has a live fs_usage:
99418 fs_usage -w -f filesys (child of thumper-demo watcher)
thumper-dev (/usr/local/thumper-2) — started 11:16, logged watching 1 bait file(s) via fs_usage — has no fs_usage, no grep, no watcher subshell left. Its watcher pipeline collapsed when demo's fs_usage took over the trace.
System-wide there is exactly one fs_usage process, belonging to the agent that started last.
Where
agent/thumper_agent.sh:437 watch_fs_usage() — runs fs_usage … | grep … | while read
agent/thumper_agent.sh:521 start_watcher() — chooses fs_usage on darwin+root
Impact
A host with two enrolled installs silently loses read detection on one of them. The bait still exists; a read of it goes undetected. High severity because read detection is the entire product.
Proposed direction
- Detect that fs_usage failed to acquire / lost the trace (pipeline EOF immediately after start) and surface it loudly (see the "watcher dies with no log" issue).
- Coordinate a single shared fs_usage sensor per host that fans out to all local installs, OR
- Fall back to the atime poll for the loser instead of going blind, OR
- At minimum, refuse/warn when a second agent on the same host would contend for fs_usage (see the "double agent on one host" issue).
Related: double-agent host guard, watcher-dies-silently, heartbeat-false-healthy, dead-watcher-not-restarted.
Summary
On macOS,
fs_usagereads the kernel trace facility (kdebug), which is effectively a single global, single-consumer resource (shared withdtrace,latency,sc_usage). When two Thumper agents run on the same host and both take the fs_usage path inwatch_fs_usage, only one can hold the trace. The agent that startsfs_usagelast wins, and the earlier agent'sfs_usageis terminated — silently disabling its read detection.Evidence (observed live)
Two agents on one Mac, both root, byte-identical
thumper_agent.sh:thumper-demo(/usr/local/thumper) — started 11:17 — has a livefs_usage:thumper-dev(/usr/local/thumper-2) — started 11:16, loggedwatching 1 bait file(s) via fs_usage— has nofs_usage, nogrep, no watcher subshell left. Its watcher pipeline collapsed when demo's fs_usage took over the trace.System-wide there is exactly one
fs_usageprocess, belonging to the agent that started last.Where
agent/thumper_agent.sh:437watch_fs_usage()— runsfs_usage … | grep … | while readagent/thumper_agent.sh:521start_watcher()— chooses fs_usage on darwin+rootImpact
A host with two enrolled installs silently loses read detection on one of them. The bait still exists; a read of it goes undetected. High severity because read detection is the entire product.
Proposed direction
Related: double-agent host guard, watcher-dies-silently, heartbeat-false-healthy, dead-watcher-not-restarted.