keeper post self-deadlocks — holds the per-shard .lock, then its spawned keeper receive-pack child blocks on the SAME lockA local keeper post --tlv be://localhost?/<shard> takes the WRITE
flock on <store>/<shard>/.lock, then forks keeper receive-pack
?/<shard> for the local wire edge. The parent keeps the flock held and
blocks reading the child's pipe; the child blocks acquiring that very
flock. Neither side can progress — a permanent self-deadlock that wedges
the shard for every other process too. Hit while another ticket agent
posted libabc; it then blocked a fresh be get …?/beagle (which recurses
into the libabc sub) indefinitely. Method Issues.
PATCH-004-land ran keeper post --at …/abc?/libabc
#40cf6df6… --tlv be://localhost?/libabc (PID 19883). /proc/locks:
PID 19883 HOLDS WRITE FLOCK on inode fd:03:681203
(/home/gritzko/.be/libabc/.lock); its child keeper receive-pack
?/libabc (PID 19888) is QUEUED on the same inode. 19883 wchan =
anon_pipe_read (waiting on the child); 19888 wchan =
locks_lock_inode_wait (waiting on the parent's flock). Stable for
many minutes — a true deadlock, not slow progress.be get be://localhost?/beagle
recursing into the libabc sub (sniff PID 15502), queued THIRD on the
same .lock and hung. Any rw op on that shard is now blocked.keeper post/wire-push must NOT hold the per-shard .lock
across the spawn of its own receive-pack (or the child must inherit
/ share the lock, not re-acquire it). No path where a single logical
post acquires the same flock twice.~/.be store make progress; a local
be://localhost post completes without wedging the shard.keeper/WIRECLI.c post/receive-pack, the .lock
flock site). Repro-first: a hermetic local be://localhost post of a
sub that exercises the post→receive-pack handoff under one process
tree; assert it exits and the .lock is released. C-only.be://localhost sub post that deadlocks on
the per-shard .lock; confirm RED (hang/timeout), then fix.keeper post opens rw (KEEP.cli.c:104
KEEPOpen(YES) → KEEP.c:423-424 FILECreate/FILELock on <leaf>/.lock)
and holds it across WIREPush (KEEP.exe.c:1036) → wcli_spawn of the local
keeper receive-pack child, whose keeper_receive_pack_inner
(KEEP.cli.c:102-110) does its own KEEPOpen(YES) on the same shard — no
release-before-spawn, no lock inheritance/skip marker anywhere in keeper/.RECVAdvanceColocatedWt (RECV.h:143 — it already
runs strictly AFTER KEEPClose+HOMEClose "so the spawned child can
acquire the store lock without deadlocking") — i.e. close/release the
keeper before the local receive-pack spawn, or pass the flock fd.