udisks: el hueco de «enchufo un USB y no pasa nada» tiene tres recetas y un sitio equivocado
El censo de gvfs dejó `udisks` como la ÚNICA frontera de verdad de aquella tanda. Su cadena, leída en las fuentes: udisks 2.11.2 → libblockdev >= 3.4 (configure.ac:175, sin perilla) libblockdev → libkmod >= 19 (configure.ac:201, sin perilla) y nada más: polkit-gobject-1 + polkit-agent-1, blkid, mount, uuid, gudev, udev, libelogind y libparted YA estaban sellados. Tres recetas, no una campaña. `kmod` publica SÓLO la librería (-Dtools=false) y sin ninguno de sus cuatro descompresores, y eso es medido, no ahorro: este kernel se construye con `-d MODULES` (recipes/linux-generic.toml:69), así que modprobe/insmod no tendrían nada que cargar y `.ko.zst` no existe. El censo de busybox ya había llegado a lo mismo por su lado. `libblockdev` lleva 4 de sus 13 plugins: fs, part, loop y swap, que son los que udisks pide y cuyo cierre está sellado. Faltan crypto (⇒ no se abre un LUKS desde el escritorio), mdraid (⇒ sin RAID software) y nvme. ⚠ TODOS los plugins vienen ENCENDIDOS por defecto en ese configure, así que hay que nombrar los nueve que no van: no declarar uno es encenderlo. Y udisksd ARRANCA igual sin ellos: usa `bd_try_init`, que registra «Failed to load the 'crypto' libblockdev plugin» y sigue. Degradación honesta, no arranque roto — pero el log lo va a decir en cada boot. ⚠ Y las dos van a `incoming-gnome/` cuando su sitio sería el corpus: **polkit NO existe en el corpus**, sólo en las dos colas de isla, y una receta del corpus no alcanza a una hermana de cola. ⇒ Con esto el USB aparece en GNOME y NO en KDE, COSMIC ni sway. Es la misma forma que ya pagaron wireplumber y NetworkManager antes de promoverse, y queda escrita en la receta. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Delta semántico
Ninguna definición cambió: el cambio es de texto, documentación o datos.
3 archivos · +177 −0
diff --git a/recipes/incoming-gnome/libblockdev.toml b/recipes/incoming-gnome/libblockdev.toml
new file mode 100644
index 00000000..0c2d84e5
--- /dev/null
+++ b/recipes/incoming-gnome/libblockdev.toml
@@ -0,0 +1,58 @@
+# libblockdev 3.5.0 — la librería de operaciones sobre dispositivos de bloque: leer una tabla de
+# particiones, identificar un sistema de ficheros, montar un `loop`. Existe acá por un único
+# consumidor: `udisks` la pide sin perilla (`configure.ac:175`, `blockdev >= 3.4`).
+#
+# ── CUATRO PLUGINS DE TRECE, Y LA CUENTA NO ES ARBITRARIA ─────────────────────────────────────
+# libblockdev se construye como un núcleo + plugins que se cargan con `dlopen`. `udisks` dice en su
+# propio código cuáles quiere (`src/udisksdaemon.c:351-360`): **part, swap, loop, mdraid, fs,
+# crypto** y nvme. Se encienden los cuatro cuyo cierre YA está sellado:
+#
+# fs → uuid + mount + ext2fs/e2p (e2fsprogs) + blkid ✅ identificar y manipular el FS
+# part → libparted >= 3.1 ✅ leer/escribir la tabla de particiones
+# loop → nada ✅ montar una ISO como disco
+# swap → uuid + blkid ✅ lo pide el núcleo de udisks
+#
+# ── ⚠ LOS TRES QUE FALTAN, CON LO QUE CUESTAN Y LO QUE ROMPEN ─────────────────────────────────
+# crypto → `libcryptsetup >= 2.3` ⇒ **no se podrá abrir un disco LUKS desde el escritorio.**
+# Es el que más se va a notar de los tres; su cadena (cryptsetup + devmapper/lvm2 +
+# json-c + argon2) es su propia unidad de trabajo.
+# mdraid → `libbytesize >= 0.1` (que a su vez pide gmp y mpfr) ⇒ sin gestión de RAID software.
+# nvme → `libnvme >= 1.3` ⇒ sin las funciones específicas de NVMe (el disco NVMe se ve y se
+# monta igual: lo que falta es SMART/namespaces propios de ese protocolo).
+#
+# ⚠ Y ESTO NO IMPIDE QUE `udisksd` ARRANQUE, lo cual es bueno y hay que saberlo: usa `bd_try_init`
+# (`udisksdaemon.c:373`), que registra `Failed to load the 'crypto' libblockdev plugin` y **sigue**.
+# O sea que el demonio levanta, los discos y los USB funcionan, y lo que falta falla en el momento
+# de usarlo. Es degradación honesta, no un arranque roto — pero el log lo va a decir en cada boot.
+#
+# ── LO DEMÁS, APAGADO POR NO TENER CONSUMIDOR ─────────────────────────────────────────────────
+# btrfs, dm, lvm, mpath, nvdimm, s390, smart, smartmontools, tools, escrow, python3. ⚠ TODOS los
+# plugins vienen ENCENDIDOS por defecto en este configure (`AS_IF([test "x$with_X" != "xno"]`), así
+# que hay que nombrarlos uno por uno: no declarar uno es encenderlo.
+#
+# `--disable-introspection`: el consumidor (udisks) es C. `--without-gtk-doc`: no hay gtk-doc.
+# ⚠ SIN `gettext-tiny`: este tarball no trae `po/` (comprobado).
+name = "libblockdev"
+version = "3.5.0"
+license = "LGPL-2.1-or-later"
+
+[source]
+tarball = "https://github.com/storaged-project/libblockdev/releases/download/3.5.0/libblockdev-3.5.0.tar.gz"
+sha256 = "bccd30e6b5d11504de60d9889ff6a2a25b07a4ec8f04070f2387e168301b3e3a"
+
+[build]
+compiler = "zig-cc"
+target = "x86_64-linux-musl"
+link = "dynamic"
+
+[build.phases]
+configure = "CFLAGS='-O2 -fPIC' PKG_CONFIG_PATH=/usr/lib/pkgconfig ./configure --build=$CBUILD --host=$CHOST --prefix=/usr --sysconfdir=/etc --enable-shared --disable-static --disable-dependency-tracking --disable-introspection --without-gtk-doc --with-fs --with-part --with-loop --with-swap --without-btrfs --without-crypto --without-dm --without-lvm --without-mdraid --without-mpath --without-nvdimm --without-nvme --without-smart --without-smartmontools --without-s390 --without-tools --without-escrow --without-python3 && sed -i 's/ -nostdlib//g' libtool"
+compile = 'make -j"$(nproc)"'
+install = 'make DESTDIR=/out install'
+
+[deps]
+# El `sed` del `-nostdlib` va por si algún plugin arrastra C++ — es la misma trampa de libtool+zig
+# que documenta `recipes/incoming-gnome/hunspell.toml`, y ponerlo cuesta nada.
+# `libudev-zero` da `libudev.pc` (el núcleo lo pide, `configure.ac:200`); `kmod` da `libkmod.pc`;
+# `util-linux` da blkid/mount/uuid; `e2fsprogs` da ext2fs/e2p; `parted` da libparted.
+build = ["make", "pkgconf", "glib", "libffi", "pcre2", "zlib-shared", "kmod", "libudev-zero", "util-linux", "e2fsprogs", "parted"]
diff --git a/recipes/incoming-gnome/udisks.toml b/recipes/incoming-gnome/udisks.toml
new file mode 100644
index 00000000..ef1a1830
--- /dev/null
+++ b/recipes/incoming-gnome/udisks.toml
@@ -0,0 +1,76 @@
+# udisks 2.11.2 — el demonio que hace que enchufar un USB signifique algo. Es la pieza que falta
+# para cerrar el hueco que quedó escrito en `recipes/incoming-gnome/gvfs.toml` y en `targets.toml`:
+# **hasta hoy esta distro montaba lo que dijera el `fstab` y lo que el usuario montara a mano.**
+#
+# ── ⚠ HOY VIVE EN `incoming-gnome/`, Y ESO ES UNA DEUDA CONOCIDA, NO EL SITIO CORRECTO ────────
+# Lo usan los CUATRO escritorios: GNOME por el monitor de volúmenes de `gvfs` (que enlaza
+# `udisks2.pc`), y KDE/COSMIC/sway por Solid y sus applets, que hablan con él **por D-Bus** sin
+# enlazarlo. El sitio natural sería el corpus, que es la única cola que las cuatro alcanzan.
+#
+# No está ahí por un motivo medido: **`polkit` NO existe en el corpus** — sólo en
+# `incoming-kde/polkit.toml` y `incoming-gnome/polkit.toml` —, y este configure lo pide duro
+# (`polkit-gobject-1` y `polkit-agent-1`, :152 y :156). Una receta del corpus no puede alcanzar a
+# una hermana de cola. O se promueve polkit al corpus —con el cuidado de no acabar con dos polkit
+# distintos en la misma ruta, que es la advertencia que `targets.toml` ya escribió para
+# NetworkManager— o se duplica esta receta en las otras colas.
+# ⇒ **Con esto, hoy el USB aparece en GNOME y no en KDE, COSMIC ni sway.** Está escrito acá porque
+# un hueco que se nombra se arregla, y es la misma forma exacta que ya pagaron `wireplumber` y
+# `networkmanager` antes de promoverse.
+#
+# ── `link = dynamic` Y LA GLib DE LA ISLA, NO la estática ─────────────────────────────────────
+# No es preferencia: `libblockdev` carga sus plugins con `dlopen`, así que el proceso acaba con el
+# núcleo y cuatro `.so` dentro. Si cada uno embebiera su propia GLib estática habría varios
+# registros de GType en el mismo proceso, que es el SIGSEGV del keystone
+# ([[dos-glib-estaticas-en-un-proceso]]). Es el mismo camino que ya sigue `networkmanager` en el
+# corpus con `glib-shared`, que también es un demonio con plugins; acá la dinámica que toca es la
+# de la isla, porque es la cola en la que vive.
+#
+# ── LAS PERILLAS ──────────────────────────────────────────────────────────────────────────────
+# --disable-acl → `libacl` (de acl/attr) no está en el catálogo. Lo que apaga: udisks pone
+# ACLs en el punto de montaje para que el usuario de la sesión activa pueda
+# escribir sin ser root. ⚠ **Esto se nota**: sin ACL, el montaje queda con los
+# permisos de siempre y el acceso se resuelve por el uid del que monta. Es el
+# hueco más fino de esta receta y merece su propia medición en la imagen.
+# --disable-smart → `libatasmart`; sin salud del disco (temperatura, horas, reasignados).
+# --disable-lvm2 --disable-btrfs --disable-iscsi --disable-lsm → módulos opcionales cuyo cierre
+# no está (lvm2, libstoragemgmt…). Ninguno hace falta para un USB.
+# --disable-man → las genera con `xsltproc` + docbook, que no están.
+# --disable-introspection → el consumidor de hoy (gvfs) es C.
+# --with-systemdsystemunitdir=no --with-tmpfilesdir=no → no hay systemd (ADR 0007).
+# --with-modprobedir / --with-modloaddir → instalan ficheros de opciones de MÓDULOS, y este kernel
+# se construye con `-d MODULES` (ver `recipes/kmod.toml`). Se dejan donde
+# upstream los pone: son datos inertes, no cuesta nada, y el día que haya
+# módulos ya están.
+#
+# ⚠ SIN `[[service]]`, y es una decisión: udisks se instala como servicio ACTIVABLE del bus de
+# sistema (`org.freedesktop.UDisks2.service` en `/usr/share/dbus-1/system-services`), que es como lo
+# despierta el monitor de volúmenes del escritorio al abrir sesión. Declararlo además como demonio
+# de arranque lo levantaría dos veces. El día que se quiera `udisksd` vivo ANTES de que haya sesión
+# —para automontar en un servidor sin pantalla, por ejemplo— eso es una Card con `scope = "system"`
+# y su propia decisión. Mismo criterio que `gnome-keyring`.
+#
+# ⚠ SIN `sed` del `ar`: sus 70 `.po` incluyen `ar.po` con CERO `msgstr[5]` (medido) ⇒ la mina del
+# msgfmt de gettext-tiny no aplica.
+name = "udisks"
+version = "2.11.2"
+license = "GPL-2.0-or-later"
+
+[source]
+tarball = "https://github.com/storaged-project/udisks/releases/download/udisks-2.11.2/udisks-2.11.2.tar.bz2"
+sha256 = "18630a8aad806bea0bc626ce97e71e50ec82c742956ac1c834a4275f8f22207b"
+
+[build]
+compiler = "zig-cc"
+target = "x86_64-linux-musl"
+link = "dynamic"
+
+[build.phases]
+configure = "CFLAGS='-O2 -fPIC' PKG_CONFIG_PATH=/usr/lib/pkgconfig ./configure --build=$CBUILD --host=$CHOST --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-shared --disable-static --disable-dependency-tracking --enable-daemon --disable-acl --disable-smart --disable-lvm2 --disable-btrfs --disable-iscsi --disable-man --disable-gtk-doc --disable-introspection --disable-nls --with-systemdsystemunitdir=no --with-tmpfilesdir=no && sed -i 's/ -nostdlib//g' libtool"
+compile = 'make -j"$(nproc)"'
+install = 'make DESTDIR=/out install'
+
+[deps]
+# `polkit` da polkit-gobject-1 Y polkit-agent-1 (las dos las pide el configure, :152 y :156).
+# `libelogind` responde al `dependency('libsystemd')` fallido (:197-208): es quien le dice a udisks
+# qué sesión está activa, que es la base de «este USB es tuyo, podés montarlo».
+build = ["make", "pkgconf", "glib", "libffi", "pcre2", "zlib-shared", "libblockdev", "kmod", "libudev-zero", "udev-pc", "libgudev", "polkit", "util-linux", "libuuid-shared", "libelogind", "parted", "e2fsprogs", "dbus", "expat"]
diff --git a/recipes/kmod.toml b/recipes/kmod.toml
new file mode 100644
index 00000000..b5fd7d3a
--- /dev/null
+++ b/recipes/kmod.toml
@@ -0,0 +1,43 @@
+# kmod 34 — la librería de módulos del kernel. Entra al catálogo por UNA razón concreta:
+# `libblockdev` la pide SIN perilla (`configure.ac:201`, `libkmod >= 19`), y sin libblockdev no hay
+# `udisks`, o sea que no hay «enchufo un USB y aparece» en ninguno de los cuatro escritorios.
+#
+# ── ⚠ ESTA RECETA PUBLICA LA LIBRERÍA Y NADA MÁS (`-Dtools=false`) ────────────────────────────
+# Y no es una poda de tamaño: **el kernel de esta distro se construye SIN módulos**. Medido en la
+# receta, no supuesto:
+#
+# recipes/linux-generic.toml:69 scripts/config … -d MODULES
+# recipes/linux-generic.toml:10 «Monolítico (MODULES off): arje-zero PID1 sin udev/modprobe»
+#
+# ⇒ `modprobe`, `insmod`, `rmmod` y `lsmod` no tendrían nada que cargar ni que listar. El censo de
+# busybox ya había llegado a la misma conclusión por su lado («kmod a BORRAR», paso 3 del plan). Lo
+# que sí hace falta es `libkmod.so`, porque libblockdev enlaza contra ella aunque en esta distro
+# nunca vaya a encontrar un módulo.
+#
+# Por la misma razón se apagan los cuatro descompresores y openssl: `-Dzstd/-Dxz/-Dzlib` descomprimen
+# módulos (`.ko.zst`, `.ko.xz`) y `-Dopenssl` verifica su firma. Sin módulos, los cinco son código
+# que no se ejecuta jamás. Las cinco librerías ESTÁN selladas en el corpus, así que encender
+# cualquiera el día que el kernel lleve módulos es una línea — y ese día habrá que encender también
+# `-Dtools=true`.
+#
+# `-Dmanpages=false`: las genera con `scdoc`, que no está en el catálogo.
+name = "kmod"
+version = "34"
+license = "LGPL-2.1-or-later"
+
+[source]
+tarball = "https://mirrors.edge.kernel.org/pub/linux/utils/kernel/kmod/kmod-34.tar.xz"
+sha256 = "12e7884484151fbd432b6a520170ea185c159f4393c7a2c2a886ab820313149a"
+
+[build]
+compiler = "zig-cc"
+target = "x86_64-linux-musl"
+link = "dynamic"
+
+[build.phases]
+configure = "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 -Dtools=false -Dmanpages=false -Ddocs=false -Dbuild-tests=false -Dzstd=disabled -Dxz=disabled -Dzlib=disabled -Dopenssl=disabled -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"]