tawasuyu

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1534Shell 199Rust 109Markdown 993713 Definiciones

gnome: esperar el NOMBRE de PolicyKit1 antes de lanzar a sus clientes

accounts-daemon y upowerd morían al arrancar: el shim de polkit se lanza en
background y tarda ~2s en adquirir org.freedesktop.PolicyKit1, ellos llamaban a
polkit_authority_get_sync() en ese hueco, D-Bus intentaba ACTIVAR el servicio y
fallaba con 'Failed to execute program ... Permission denied'.

Lo peor era el informe: los tres esperar_nombre estaban al final, así que para
cuando corrían el shim ya tenía el nombre y el resumen daba 'PolicyKit1 OK'
sobre dos clientes ya muertos. Un chequeo posterior a la carrera no la mide.

esperar_nombre pasa a definirse antes del primer daemon y el bloque de polkit
espera su propio nombre antes de que arranque ningún cliente suyo. Lanzar en
orden no es estar listo en orden.

De paso queda cerrado el ítem 4 del runbook: validación CON PANTALLA (DISP=gtk)
del Overview con el PID1 sellado nuevo — 689 colores distintos, con evidencia.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

c0055331c738622982f38e4702b402db0e443803 · por sergio · (hace 2 meses) · padre 84e088fd1 · ver el árbol en este commit

Delta semántico

Ninguna definición cambió: el cambio es de texto, documentación o datos.

3 archivos · +84 −31

diff --git a/docs/evidencia/gnome-shell-qemu-2026-08-03-pid1-sellado.png b/docs/evidencia/gnome-shell-qemu-2026-08-03-pid1-sellado.png
new file mode 100644
index 00000000..71b03f21
Binary files /dev/null and b/docs/evidencia/gnome-shell-qemu-2026-08-03-pid1-sellado.png differ
diff --git a/docs/runbooks/gnome-qemu-desktop.md b/docs/runbooks/gnome-qemu-desktop.md
index 932bbfdc..8941ae6e 100644
--- a/docs/runbooks/gnome-qemu-desktop.md
+++ b/docs/runbooks/gnome-qemu-desktop.md
@@ -404,8 +404,43 @@ elige `/dev/dri/card0` como primaria sin quejarse. Es el rédito directo de la c
    (ver el comentario de la receta: por qué NO se cherry-pickeó, con la medición).
    **La lección general: antes de arreglar un WARN, buscá quién lo emite y si ya está arreglado
    upstream.** Nuestro pin estaba 3951 commits detrás y nadie lo había mirado.
-4. Con la capa JS viva: validar CON PANTALLA (`DISP=gtk`), nunca sólo por serial — regla heredada de
-   KDE ([[metal-dual-desktop-en-curso]]).
+4. ✅ **HECHO (2026-08-03)** — validado CON PANTALLA de verdad (`DISP=gtk`, ventana en el laptop) y no
+   sólo por `screendump`: el Overview pinta con el PID1 sellado nuevo, **689 colores distintos**, azul
+   GNOME `(2,60,136)` y grises del shell `(34,34,38)` al frente, cursor visible.
+   Evidencia: [`gnome-shell-qemu-2026-08-03-pid1-sellado.png`](../evidencia/gnome-shell-qemu-2026-08-03-pid1-sellado.png).
+   **Y aplicar la regla pagó otra vez**: el arranque destapó una regresión que el serial daba por
+   verde — ver abajo.
+
+### La carrera de PolicyKit1: el resumen final decía OK y los clientes ya estaban muertos
+
+Arrancando para la validación con pantalla, `accounts-daemon` y `upowerd` **murieron los dos**:
+
+```
+Error calling StartServiceByName for org.freedesktop.PolicyKit1:
+  Failed to execute program org.freedesktop.PolicyKit1: Permission denied
+Failed to initialize daemon
+```
+
+El comentario del script ya decía que arje-polkit-compat «VA ANTES que accounts-daemon y upowerd», y
+**iba antes** — en el orden de las líneas. Pero se lanza en background y tarda ~2 s en adquirir
+`org.freedesktop.PolicyKit1`, mientras los otros dos arrancan de inmediato y llaman a
+`polkit_authority_get_sync()` dentro de ese hueco. Sin dueño del nombre, D-Bus intenta ACTIVAR el
+servicio, la activación falla, y los dos daemons se mueren.
+
+**Lo peligroso no fue el fallo sino el informe.** Los tres `esperar_nombre` estaban todos al final:
+para cuando corrían, el shim ya tenía el nombre y el resumen imprimía `bus: org.freedesktop.PolicyKit1
+OK` sobre dos clientes que hacía rato eran cadáveres. Un chequeo que corre después de la carrera no la
+mide.
+
+El arreglo es mover la espera al PRODUCTOR: `esperar_nombre` se define antes del primer daemon, y el
+bloque de polkit espera su propio nombre **antes** de que se lance ningún cliente suyo. Es la misma
+lección de «un pid no es un servicio» aplicada del otro lado: *lanzar en orden no es estar listo en
+orden*. Después del fix: `PolicyKit1 OK` → `accounts-daemon lanzado` → `upowerd sigue vivo` →
+`Accounts OK` → `UPower OK`.
+
+Dato suelto que dejó el mismo arranque: **colord ahora MUERE** («colord MURIÓ al arrancar») en vez de
+quedarse vivo sin adquirir el nombre. Su log sigue cortándose después de abrir las tres bases de datos.
+Cambió el síntoma, no la causa conocida; el ítem sigue aparcado.
 
 ## Recetas nuevas de esta etapa
 
diff --git a/scripts/gnome/gnome-start-qemu.sh b/scripts/gnome/gnome-start-qemu.sh
index f0639914..bc4de733 100755
--- a/scripts/gnome/gnome-start-qemu.sh
+++ b/scripts/gnome/gnome-start-qemu.sh
@@ -214,14 +214,59 @@ export XDG_SESSION_ID=1
 export XDG_SEAT=seat0
 export XDG_VTNR=1
 
+# ── ESPERAR EL NOMBRE, NO EL PROCESO ────────────────────────────────────────────────────────────
+# El paso que faltaba, y es la otra mitad de «un pid no es un servicio»: comprobar que el daemon
+# ADQUIRIÓ su nombre en el bus. Se le da tiempo y, si no aparece, se vuelca su log y la lista de
+# nombres del bus — que es el dato que dice si el problema es «no arrancó», «arrancó y no pidió el
+# nombre» o «lo pidió y se lo negaron».
+# $3 = décimas de segundo a esperar (default 20 = 10 s). colord necesita más: en el PRIMER arranque
+# crea sus tres bases de datos en /var/lib/colord y escanea los directorios de perfiles ICC antes de
+# pedir el nombre, y con 10 s daba «NO apareció» sin estar colgado — o sea un falso negativo.
+#
+# Se define ACÁ ARRIBA —antes del primer daemon— y no al final junto a las llamadas, porque el bloque
+# de polkit de abajo la necesita para poder ESPERAR antes de lanzar a sus clientes.
+esperar_nombre() {
+  n="$1"; log="$2"; lim="${3:-20}"; i=0
+  while [ $i -lt "$lim" ]; do
+    if dbus-send --system --dest=org.freedesktop.DBus --print-reply \
+         /org/freedesktop/DBus org.freedesktop.DBus.NameHasOwner "string:$n" 2>/dev/null \
+       | grep -q "boolean true"; then
+      say "bus: $n OK"
+      return 0
+    fi
+    i=$((i+1)); sleep 0.5
+  done
+  say "!! bus: $n NO apareció en $((lim/2))s"
+  [ -n "$log" ] && [ -s "$log" ] && dump "$log"
+  say "nombres en el bus de sistema:"
+  dbus-send --system --dest=org.freedesktop.DBus --print-reply \
+    /org/freedesktop/DBus org.freedesktop.DBus.ListNames 2>/dev/null \
+    | tr -d '" ' | grep -v '^\s*$' > /tmp/busnames.log
+  dump /tmp/busnames.log
+  return 1
+}
+
 # arje-polkit-compat: el PolicyKit1 del fractal. **VA ANTES que accounts-daemon y upowerd**, y el
 # orden no es estético: los dos se bloquean en `polkit_authority_get_sync()` al arrancar, así que si
 # `org.freedesktop.PolicyKit1` no está en el bus se quedan conectados pero SIN adquirir su nombre —y
 # gnome-shell después espera 25 s por cada uno—. Nuestra receta `polkit` es libs-only a propósito
 # (el demonio lo pone arje). Ojo: el shim autoriza TODO; ver recipes/arje-polkit-compat.toml.
+#
+# ⚠ Y «antes» tiene que ser POR EL NOMBRE, no por el orden de las líneas. Lanzarlo primero no alcanza:
+# se lanza en background y tarda ~2 s en adquirir `org.freedesktop.PolicyKit1`, mientras accounts-daemon
+# y upowerd arrancan de inmediato y llaman a `polkit_authority_get_sync()` en ese hueco. Entonces D-Bus
+# intenta ACTIVAR el servicio (nadie tiene el nombre todavía) y falla:
+#   Error calling StartServiceByName for org.freedesktop.PolicyKit1:
+#     Failed to execute program org.freedesktop.PolicyKit1: Permission denied
+# y los dos daemons se MUEREN («Failed to initialize daemon»). Después el shim adquiere el nombre
+# tranquilo y el chequeo del final dice `PolicyKit1 OK` — o sea que el resumen final da verde y los
+# clientes ya están muertos. La carrera es real y la ganaba cualquiera: es la misma lección de «un pid
+# no es un servicio», aplicada al productor en vez de al consumidor.
 if [ -x /usr/bin/arje-polkit-compat ]; then
   /usr/bin/arje-polkit-compat >/tmp/polkit-compat.log 2>&1 &
   say "arje-polkit-compat lanzado (pid $!)"
+  esperar_nombre org.freedesktop.PolicyKit1 /tmp/polkit-compat.log \
+    || say "!! sigo igual: accounts-daemon y upowerd van a fallar al pedir la autoridad"
 else
   say "!! sin arje-polkit-compat — accounts-daemon y upowerd se van a colgar pidiendo autorización"
 fi
@@ -266,34 +311,6 @@ else
   say "!! sin upowerd — el shell va a esperar 25s a su activación D-Bus y seguir sin batería"
 fi
 
-# ── ESPERAR EL NOMBRE, NO EL PROCESO ────────────────────────────────────────────────────────────
-# El paso que faltaba, y es la otra mitad de «un pid no es un servicio»: comprobar que el daemon
-# ADQUIRIÓ su nombre en el bus. Se le da tiempo y, si no aparece, se vuelca su log y la lista de
-# nombres del bus — que es el dato que dice si el problema es «no arrancó», «arrancó y no pidió el
-# nombre» o «lo pidió y se lo negaron».
-# $3 = décimas de segundo a esperar (default 20 = 10 s). colord necesita más: en el PRIMER arranque
-# crea sus tres bases de datos en /var/lib/colord y escanea los directorios de perfiles ICC antes de
-# pedir el nombre, y con 10 s daba «NO apareció» sin estar colgado — o sea un falso negativo.
-esperar_nombre() {
-  n="$1"; log="$2"; lim="${3:-20}"; i=0
-  while [ $i -lt "$lim" ]; do
-    if dbus-send --system --dest=org.freedesktop.DBus --print-reply \
-         /org/freedesktop/DBus org.freedesktop.DBus.NameHasOwner "string:$n" 2>/dev/null \
-       | grep -q "boolean true"; then
-      say "bus: $n OK"
-      return 0
-    fi
-    i=$((i+1)); sleep 0.5
-  done
-  say "!! bus: $n NO apareció en $((lim/2))s"
-  [ -n "$log" ] && [ -s "$log" ] && dump "$log"
-  say "nombres en el bus de sistema:"
-  dbus-send --system --dest=org.freedesktop.DBus --print-reply \
-    /org/freedesktop/DBus org.freedesktop.DBus.ListNames 2>/dev/null \
-    | tr -d '" ' | grep -v '^\s*$' > /tmp/busnames.log
-  dump /tmp/busnames.log
-  return 1
-}
 # ── AUDIO: PipeWire (decisión del usuario, 2026-07-29) ──────────────────────────────────────────
 # Van TRES procesos y el orden importa, porque cada uno es cliente del anterior:
 #   1. `pipewire`        — el servidor. Crea $XDG_RUNTIME_DIR/pipewire-0.
@@ -394,7 +411,8 @@ else
 fi
 
 esperar_nombre org.freedesktop.login1 /tmp/logind-compat.log
-esperar_nombre org.freedesktop.PolicyKit1 /tmp/polkit-compat.log
+# PolicyKit1 NO se chequea acá: ya se esperó arriba, antes de lanzar a sus clientes. Chequearlo sólo
+# al final era precisamente lo que dejaba pasar la carrera con verde.
 esperar_nombre org.freedesktop.Accounts /tmp/accounts-daemon.log
 esperar_nombre org.freedesktop.UPower /tmp/upowerd.log
 esperar_nombre org.freedesktop.ColorManager /tmp/colord.log 80   # 40 s: ver el comentario