cazadores: setsid + matar el GRUPO — mataban el bwrap y el firefox sobrevivía
Segunda vez el mismo día: un firefox colgado de la verificación A/B se quedó con el lock de build de la granja. La causa es del arnés, no de firefox: 'kill $BW' mata el bwrap EXTERIOR, que no es el init del namespace de PID, así que el proceso de dentro sigue vivo — y si el arnés corría bajo flock, hereda el fd del lock y deja a la granja muda hasta que alguien mire. Medido con control negativo y positivo: matar sólo el bwrap → queda 1 firefox vivo (reproduce la fuga) setsid + matar grupo → quedan 0 (arreglado) Se documenta además que el 'flock' del uso lleva '-o', que no es opcional. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
This commit is contained in:
@@ -26,7 +26,9 @@
|
||||
# matar a alguien es a él, nunca a un build de la granja. Y toda la caza corre con el flock de la
|
||||
# granja tomado, para que no arranque una compilación de 4 h mientras se estrangula la RAM.
|
||||
#
|
||||
# Uso: N=20 scripts/diagnostico/cazar-cuelgue-bajo-presion.sh
|
||||
# Uso: N=20 flock -o work/.farm-build.lock scripts/diagnostico/cazar-cuelgue-bajo-presion.sh
|
||||
# El `-o` NO es opcional: sin él, un firefox que se cuelgue hereda el fd del lock y lo
|
||||
# retiene DESPUÉS de que el arnés termine (regla 1 de CLAUDE.md). Pasó dos veces.
|
||||
set -u
|
||||
RAIZ=/mnt/vvv/hammer; R=$RAIZ/store/.rootfs/sway-v2
|
||||
AQUI=$(cd "$(dirname "$0")" && pwd)
|
||||
@@ -55,7 +57,12 @@ for NIVEL in 0 2000 1200 700; do
|
||||
colg=0; muer=0; ok=0
|
||||
for i in $(seq 1 $N); do
|
||||
d0=$(disp); p0=$(psi); o0=$(ooms)
|
||||
bwrap --ro-bind "$R" / --ro-bind /usr/lib/musl/lib/libc.so /lib/ld-musl-x86_64.so.1 \
|
||||
# ⚠ `setsid` + matar el GRUPO, no el bwrap (medido 2026-09-08, DOS veces el mismo día).
|
||||
# `kill $BW` mata el bwrap EXTERIOR, que no es el init del namespace de PID: el firefox de
|
||||
# dentro sobrevive. Y si el arnés corría bajo `flock`, ese superviviente HEREDA el fd del lock
|
||||
# y deja a la granja sin poder compilar hasta que alguien lo note — pasó hora y media, en
|
||||
# silencio. Medido: matando sólo el bwrap queda 1 firefox vivo; matando el grupo, 0.
|
||||
setsid bwrap --ro-bind "$R" / --ro-bind /usr/lib/musl/lib/libc.so /lib/ld-musl-x86_64.so.1 \
|
||||
--ro-bind "${FF[$(( i % 2 ))]}/usr/lib/firefox" /usr/lib/firefox \
|
||||
--dev /dev --proc /proc --tmpfs /run --tmpfs /tmp --unshare-pid \
|
||||
--ro-bind "$AQUI" /bench --bind "$SAL" /salida --unshare-user --uid 0 --gid 0 \
|
||||
@@ -80,7 +87,7 @@ for NIVEL in 0 2000 1200 700; do
|
||||
echo " rss=$(awk '/^VmRSS:/{print $2,$3}' /proc/$p/status 2>/dev/null)"; } >>"$D/procesos.txt" 2>/dev/null
|
||||
done
|
||||
cp "$SAL/nav-$i.log" "$D/navegador.log" 2>/dev/null
|
||||
kill -TERM $BW 2>/dev/null; sleep 3; kill -KILL $BW 2>/dev/null; printf 'X'
|
||||
kill -TERM -$BW 2>/dev/null; sleep 3; kill -KILL -$BW 2>/dev/null # el GRUPO; printf 'X'
|
||||
else
|
||||
wait $BW; rc=$?
|
||||
od=$(( $(ooms) - o0 ))
|
||||
|
||||
@@ -130,7 +130,12 @@ PAGS=(fuera-del-corpus.html del-corpus.html) # LAS DEL BANCO: es donde ocurrie
|
||||
colgadas=0
|
||||
for i in $(seq 1 $N); do
|
||||
art=${FF[$(( i % 4 ))]}; pag=${PAGS[$(( i % 2 ))]}
|
||||
bwrap --ro-bind "$R" / --ro-bind /usr/lib/musl/lib/libc.so /lib/ld-musl-x86_64.so.1 \
|
||||
# ⚠ `setsid` + matar el GRUPO, no el bwrap: `kill $BW` mata el bwrap EXTERIOR, que no es el init
|
||||
# del namespace de PID, y el firefox de dentro SOBREVIVE. Si el arnés corre bajo `flock`, ese
|
||||
# superviviente hereda el fd del lock y deja a la granja sin compilar hasta que alguien lo note
|
||||
# (pasó dos veces el 2026-09-08, hora y media la primera). Medido: matando sólo el bwrap queda
|
||||
# 1 firefox vivo; matando el grupo, 0.
|
||||
setsid bwrap --ro-bind "$R" / --ro-bind /usr/lib/musl/lib/libc.so /lib/ld-musl-x86_64.so.1 \
|
||||
--ro-bind "$art/usr/lib/firefox" /usr/lib/firefox \
|
||||
--dev /dev --proc /proc --tmpfs /run --tmpfs /tmp --unshare-pid \
|
||||
--ro-bind "$S/bench" /bench --bind "$S/caza4" /salida --unshare-user --uid 0 --gid 0 \
|
||||
@@ -154,7 +159,7 @@ for i in $(seq 1 $N); do
|
||||
echo " syscall=$(cut -c1-70 /proc/$p/syscall 2>/dev/null)"
|
||||
echo " rss=$(awk '/^VmRSS:/{print $2,$3}' /proc/$p/status 2>/dev/null)"; } >> "$D/procesos.txt" 2>/dev/null
|
||||
done
|
||||
kill -TERM $BW 2>/dev/null; sleep 3; kill -KILL $BW 2>/dev/null
|
||||
kill -TERM -$BW 2>/dev/null; sleep 3; kill -KILL -$BW 2>/dev/null # el GRUPO
|
||||
printf 'X'
|
||||
else printf '.'; fi
|
||||
done
|
||||
|
||||
@@ -26,7 +26,12 @@ for i in $(seq 1 $N); do
|
||||
for k in viejo nuevo; do
|
||||
[ $k = viejo ] && ENV="$VIEJO" || ENV="$NUEVO"
|
||||
SAL=$(mktemp -d)
|
||||
bwrap --ro-bind "$R" / --ro-bind /usr/lib/musl/lib/libc.so /lib/ld-musl-x86_64.so.1 \
|
||||
# ⚠ `setsid` + matar el GRUPO, no el bwrap (medido 2026-09-08, DOS veces el mismo día).
|
||||
# `kill $BW` mata el bwrap EXTERIOR, que no es el init del namespace de PID: el firefox de
|
||||
# dentro sobrevive. Y si el arnés corría bajo `flock`, ese superviviente HEREDA el fd del lock
|
||||
# y deja a la granja sin poder compilar hasta que alguien lo note — pasó hora y media, en
|
||||
# silencio. Medido: matando sólo el bwrap queda 1 firefox vivo; matando el grupo, 0.
|
||||
setsid bwrap --ro-bind "$R" / --ro-bind /usr/lib/musl/lib/libc.so /lib/ld-musl-x86_64.so.1 \
|
||||
--ro-bind "$A/usr/lib/firefox" /usr/lib/firefox --dev /dev --proc /proc --tmpfs /run --tmpfs /tmp \
|
||||
--unshare-pid --ro-bind "$AQUI" /bench --bind "$SAL" /salida --unshare-user --uid 0 --gid 0 \
|
||||
--setenv PATH /usr/bin:/bin --setenv APAGA "$ENV" \
|
||||
@@ -37,7 +42,7 @@ for i in $(seq 1 $N); do
|
||||
while kill -0 $BW 2>/dev/null && [ $t -lt $UMBRAL ]; do sleep 1; t=$((t+1)); done
|
||||
if kill -0 $BW 2>/dev/null; then
|
||||
COLG[$k]=$(( ${COLG[$k]} + 1 )); cp -r "$SAL" "$RAIZ/work/colgada-$k-$i" 2>/dev/null
|
||||
kill -TERM $BW 2>/dev/null; sleep 3; kill -KILL $BW 2>/dev/null
|
||||
kill -TERM -$BW 2>/dev/null; sleep 3; kill -KILL -$BW 2>/dev/null # el GRUPO
|
||||
else
|
||||
wait $BW 2>/dev/null
|
||||
SEGV[$k]=$(( ${SEGV[$k]} + $(grep -c 'exited on signal 11' "$SAL/nav.log") ))
|
||||
|
||||
Reference in New Issue
Block a user