gnome: el compositor SUBE ENTERO en headless — el muro DRM es libinput, y aparece accountsservice
Experimento decisivo: `gnome-shell --headless --virtual-monitor 1280x800`. El
backend headless crea el seat con META_SEAT_NATIVE_FLAG_NO_LIBINPUT, o sea que
saltea init_libinput() — justo el último paso del hilo de input antes de señalar
`input_thread_initialized` (meta-seat-impl.c:3098). Resultado:
libmutter-Message: Added virtual monitor Meta-0
libmutter-Message: Using Wayland display name 'wayland-0'
== compositor OK (wayland-0) — el shell ES el display server
⇒ **CONFIRMADO: el bloqueo del camino DRM está en libinput/udev, no en el resto
del arranque.** Todo lo demás de mutter funciona. Primer sospechoso libudev-zero.
Y con el compositor arriba aparece el muro siguiente, que es de otra naturaleza:
Gjs-CRITICAL: JS ERROR: Requiring AccountsService, version 1.0:
Typelib file for namespace 'AccountsService' not found
LA LECCIÓN DE MÉTODO: gnome-shell selló con su cierre de build COMPLETO (108/108)
y aun así la sesión muere pidiendo este typelib. **El cierre de build no es el
cierre de runtime**: todo lo que el shell carga por `imports.gi.*` desde
JavaScript es invisible al grafo de deps. Se encuentra ARRANCANDO, no compilando.
Se autoró recipes/incoming-gnome/accountsservice.toml. El configure pasa entero
—tres seds verificados contra el build real: generate-version.sh (deriva la
versión del nombre del DIRECTORIO, que en el sandbox es /src, y la rama git usa
`date`, o sea no-determinista), la aserción de wtmp (musl no define WTMPX_FILENAME
ni _PATH_WTMPX) y subdir('tests') (arrastra mocklibc, que llama fgetgrent, ausente
en musl)—. Ojo: -Dsystemdsystemunitdir tiene que ser literalmente `no`; con la
cadena vacía el meson interpreta "averiguá el directorio" y aserta pidiendo
systemd.pc.
NO SELLA todavía, y la frontera está contada símbolo por símbolo, no estimada:
· libelogind exporta 14 símbolos (los que pedía mutter) y accountsservice usa
OCHO que faltan: sd_get_sessions, sd_seat_can_multi_session,
sd_session_get_display y los cinco de sd_login_monitor_*. Estos últimos son
la parte con enjundia: no son getters sino una API de NOTIFICACIÓN (un fd
poll-able). Sobre el diseño actual el camino natural es inotify sobre
/run/systemd/{sessions,seats,users}.
· fgetspent_r no existe en musl (extensión glibc de /etc/shadow, usada en
src/daemon.c:265): necesita shim o parche a la variante no-reentrante.
Ninguno de los dos es de accountsservice: son huecos de NUESTRA capa de compat.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
# accountsservice 23.13.9 — el servicio D-Bus de cuentas de usuario (nombre, avatar, idioma, si es
|
||||
# administrador). Lo pide gnome-shell desde JAVASCRIPT, no desde C: por eso no aparecía en el
|
||||
# meson.build de la cima ni en su cierre de build, y sólo se destapó ARRANCANDO la sesión:
|
||||
#
|
||||
# Gjs-CRITICAL: JS ERROR: Requiring AccountsService, version 1.0:
|
||||
# Typelib file for namespace 'AccountsService', version '1.0' not found
|
||||
# Execution of main.js threw exception
|
||||
#
|
||||
# Lección del método: **el cierre de BUILD no es el cierre de RUNTIME**. gnome-shell selló con
|
||||
# 108/108 recetas y aun así le falta esto, porque `imports.gi.AccountsService` se resuelve en tiempo
|
||||
# de ejecución. Toda dep que el shell cargue por typelib desde JS es invisible al build.
|
||||
#
|
||||
# -Delogind=true es la pieza que hace que esto entre gratis: accountsservice pide `libsystemd` por
|
||||
# defecto (meson.build:219) y con esta opción pide `libelogind` (:217), que YA está sellada —
|
||||
# arje-sdlogin-compat, con Version 255 en su .pc, por encima del >= 229.4 que exige. Es la quinta vez
|
||||
# en la campaña que la C-ABI de logind aparece, y la primera que se resuelve sin esquivarla.
|
||||
#
|
||||
# Apagados:
|
||||
# -Dvapi=false → no hay valac en el corpus.
|
||||
# -Ddocbook=false -Dgtk_doc=false → xmlto/gtk-doc.
|
||||
# -Dsystemdsystemunitdir=no → no instala units de systemd; acá PID1 es arje-zero. Ojo: el valor
|
||||
# tiene que ser literalmente `no`, NO la cadena vacía — con vacía el meson
|
||||
# interpreta "averiguá el directorio" y ASERTA pidiendo systemd.pc (:183).
|
||||
# libxcrypt es `required: false` (meson.build:161) ⇒ no hace falta receta: sin ella el servicio no
|
||||
# cambia contraseñas, que no es lo que el shell le pide (le pide el usuario y su avatar).
|
||||
#
|
||||
# `generate-version.sh` se reemplaza por un `echo` de la versión. El script del tarball deriva la
|
||||
# versión del NOMBRE DEL DIRECTORIO (`basename $PWD | sed 's/^accountsservice-\(.*\)$/\1/'`), y en el
|
||||
# sandbox de hammer el árbol de fuentes es `/src` ⇒ no matchea y aborta con "Version unknown". Fijarla
|
||||
# además la vuelve DETERMINISTA: la otra rama del script (la de checkout git) calcula la versión con
|
||||
# `date` sobre el último commit, que es exactamente lo que un store direccionable por contenido no
|
||||
# puede tolerar.
|
||||
#
|
||||
# El otro sed borra una ASERCIÓN sobre wtmp (meson.build:107). accountsservice busca el fichero de
|
||||
# histórico de logins probando `WTMPX_FILENAME` y `_PATH_WTMPX`; **musl no define ninguno de los dos**
|
||||
# —no implementa wtmp—, así que cae a la rama final, que exige que `/var/log/utx.log` EXISTA en el
|
||||
# constructor y aborta si no. Se borra sólo la línea del assert: la rama igual deja
|
||||
# `PATH_WTMP='/var/log/utx.log'`, o sea que el servicio vigila esa ruta y, como nunca aparece, no
|
||||
# reporta histórico de sesiones. Lo que el shell le pide —el usuario, su nombre y su avatar— no
|
||||
# depende de wtmp. La alternativa era `touch` ese fichero en el sandbox para que el chequeo pasara,
|
||||
# que es hacer verdadera una premisa falsa; preferible borrar el chequeo y decir por qué.
|
||||
#
|
||||
# Y un tercer sed saca `subdir('tests')` (:235), que accountsservice no expone como opción. No es por
|
||||
# ahorrar tiempo de build: los tests arrastran el subproyecto `mocklibc`, que llama `fgetgrent()` —
|
||||
# una extensión GNU que **musl no implementa**. No hay forma de compilarlo acá, y lo que se pierde es
|
||||
# la suite del upstream, no la librería.
|
||||
#
|
||||
# El sed saca `subdir('po')`. QUINTA vez que el msgfmt de gettext-tiny obliga a esto (iso-codes, gcr,
|
||||
# eds, gnome-shell y ahora ésta). Ya no es un gotcha: es la deuda de autorar el gettext de GNU.
|
||||
#
|
||||
# ISLA DINÁMICA: -Dintrospection=true + shared, porque lo que falta es justamente el TYPELIB.
|
||||
#
|
||||
# ══ ⛔ NO SELLA TODAVÍA — FRONTERA MEDIDA, NO ADIVINADA (2026-07-29) ═════════════════════════════
|
||||
# El configure pasa entero (los tres seds y las opciones de arriba están verificados contra el build
|
||||
# real); lo que corta es el COMPILE, y por dos motivos independientes:
|
||||
#
|
||||
# 1. LA C-ABI DE sd-login SE QUEDA CORTA. `libelogind` (arje-sdlogin-compat) exporta 14 símbolos —
|
||||
# los que necesitaba mutter— y accountsservice usa OCHO que no están:
|
||||
# sd_get_sessions · sd_seat_can_multi_session · sd_session_get_display
|
||||
# sd_login_monitor (el tipo) · sd_login_monitor_new · sd_login_monitor_unref
|
||||
# sd_login_monitor_get_fd · sd_login_monitor_flush
|
||||
# Los cinco de `sd_login_monitor_*` son la parte con enjundia: no son getters sobre ficheros sino
|
||||
# una API de NOTIFICACIÓN (un fd que se puede meter en un poll y despierta cuando cambia el
|
||||
# estado de sesiones). Sobre el diseño actual —leer /run/systemd/{sessions,seats,users}— el
|
||||
# camino natural es un inotify sobre esos directorios.
|
||||
#
|
||||
# 2. `fgetspent_r` NO EXISTE EN musl. Es la variante reentrante de la API de /etc/shadow, extensión
|
||||
# de glibc. La usa src/daemon.c:265 para saber si una cuenta tiene contraseña. Necesita un shim
|
||||
# o un parche que use la variante no-reentrante.
|
||||
#
|
||||
# NINGUNO DE LOS DOS es de accountsservice: son huecos de NUESTRA capa de compatibilidad. La receta
|
||||
# queda como mapa honesto de la cadena —el mismo criterio que gnome-session y gnome-settings-daemon
|
||||
# en esta cola—, con la frontera contada símbolo por símbolo en vez de estimada.
|
||||
#
|
||||
# CÓMO SE DESTAPÓ, y es la lección de método: gnome-shell selló con su cierre de build COMPLETO
|
||||
# (108/108) y aun así la sesión murió pidiendo este typelib. **El cierre de build no es el cierre de
|
||||
# runtime**: todo lo que el shell carga por `imports.gi.*` desde JavaScript es invisible al grafo de
|
||||
# deps. Se encuentra arrancando, no compilando.
|
||||
name = "accountsservice"
|
||||
version = "23.13.9"
|
||||
|
||||
[source]
|
||||
tarball = "https://www.freedesktop.org/software/accountsservice/accountsservice-23.13.9.tar.xz"
|
||||
sha256 = "adda4cdeae24fa0992e7df3ffff9effa7090be3ac233a3edfdf69d5a9c9b924f"
|
||||
|
||||
[build]
|
||||
compiler = "zig-cc"
|
||||
target = "x86_64-linux-musl"
|
||||
link = "dynamic"
|
||||
|
||||
[build.phases]
|
||||
configure = "printf '#!/bin/sh\\necho 23.13.9\\n' > generate-version.sh && sed -i \"/^subdir('po')$/d\" meson.build && sed -i '/Do not know which filename to watch for wtmp changes/d' meson.build && sed -i \"/^subdir('tests')$/d\" meson.build && PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload -Ddefault_library=shared -Delogind=true -Dintrospection=true -Dvapi=false -Ddocbook=false -Dgtk_doc=false -Dsystemdsystemunitdir=no -Dc_args=-Wno-error=date-time"
|
||||
compile = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output"
|
||||
install = "PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild"
|
||||
|
||||
[deps]
|
||||
build = ["meson", "samurai", "python3", "pkgconf", "gettext-tiny", "py3-setuptools", "gi-foreign-girs", "gobject-introspection", "glib", "glib-introspected", "polkit", "dbus-shared", "libelogind", "libffi", "pcre2", "zlib-shared", "expat"]
|
||||
@@ -13,6 +13,8 @@
|
||||
set -u
|
||||
# getty ejecuta este script DIRECTO ⇒ PATH viene vacío. Primero eso, antes de invocar nada.
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
# El modo lo hornea la imagen (GNOME_MODE=... en scripts/gnome/qemu-desktop-image.sh).
|
||||
[ -r /etc/gnome-mode ] && . /etc/gnome-mode
|
||||
say() { echo "== gnome-qemu :: $*" | tee -a /dev/console /dev/ttyS0 2>/dev/null; }
|
||||
dump() { echo "---- $1 ----" > /dev/ttyS0 2>/dev/null; cat "$1" > /dev/ttyS0 2>/dev/null; }
|
||||
|
||||
@@ -177,8 +179,17 @@ if [ "${DIAG:-1}" = 1 ]; then
|
||||
fi
|
||||
|
||||
say "typelibs visibles: $(ls /usr/lib/girepository-1.0/*.typelib 2>/dev/null | wc -l) sistema + $(ls /usr/lib/gnome-shell/*.typelib 2>/dev/null | wc -l) del shell"
|
||||
say "lanzando gnome-shell --wayland (DRM virtio, software GL)..."
|
||||
/usr/bin/gnome-shell --wayland >/tmp/gnome-shell.log 2>&1 &
|
||||
# GNOME_MODE=headless — EXPERIMENTO DECISIVO, no un modo de producción. El backend headless de
|
||||
# mutter crea el seat con META_SEAT_NATIVE_FLAG_NO_LIBINPUT, o sea que SALTEA `init_libinput()`,
|
||||
# que es justo el último paso del hilo de input antes de señalar `input_thread_initialized`
|
||||
# (meta-seat-impl.c:3098). Si en headless aparece wayland-0, el bloqueo está en libinput/udev y no
|
||||
# en el resto del arranque; si tampoco aparece, el problema es anterior (keymap, input settings).
|
||||
case "${GNOME_MODE:-drm}" in
|
||||
headless) SHELL_ARGS="--headless --virtual-monitor 1280x800" ;;
|
||||
*) SHELL_ARGS="--wayland" ;;
|
||||
esac
|
||||
say "lanzando gnome-shell $SHELL_ARGS (modo=${GNOME_MODE:-drm})..."
|
||||
/usr/bin/gnome-shell $SHELL_ARGS >/tmp/gnome-shell.log 2>&1 &
|
||||
SHELL_PID=$!
|
||||
# stream EN VIVO al serial (busybox sed no soporta -u ⇒ tail -f directo, sin pipes).
|
||||
( echo "==== gnome-shell.log (stream vivo) ===="; tail -f /tmp/gnome-shell.log ) > /dev/ttyS0 2>/dev/null &
|
||||
|
||||
@@ -138,6 +138,10 @@ for f in passwd:messagebus:x:81:81:messagebus:/dev/null:/sbin/nologin group:mess
|
||||
fi
|
||||
done
|
||||
|
||||
# GNOME_MODE se hornea como fichero: el getty ejecuta gnome-start sin ambiente heredable.
|
||||
printf 'GNOME_MODE=%s\n' "${GNOME_MODE:-drm}" > "$MERGED/etc/gnome-mode"
|
||||
echo "==> modo de arranque: ${GNOME_MODE:-drm}"
|
||||
|
||||
echo "==> instalando /usr/bin/gnome-start"
|
||||
install -Dm755 scripts/gnome/gnome-start-qemu.sh "$MERGED/usr/bin/gnome-start"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user