el frente kmod no existe: los kernels de takana no tienen módulos

Fui a escribir el kmod en Rust que el plan pide —la pieza más grande que
quedaba— y lo primero fue buscar contra qué módulos probarlo. No hay ninguno:

  · 0 ficheros .ko en los artefactos sellados de los cuatro kernels (sólo
    boot/bzImage y el .config)
  · 0 recetas del corpus hacen modules_install
  · 0 drivers `=m` en los .config sellados (contra 1809 `=y` en linux-metal)
  · `# CONFIG_MODULES is not set` en los tres kernels que están en el store
  · nadie en el repo enciende CONFIG_MODULES

Sin CONFIG_MODULES el kernel ni siquiera implementa init_module/delete_module: un
insmod escrito en Rust recibiría ENOSYS. Los 6 applets de kmod no son escritura,
son 6 applets a retirar. Y con ellos otros 3: DEVTMPFS_MOUNT=y hace que el kernel
cree y monte /dev, no hay UEVENT_HELPER, y libudev-zero ya viaja en los 8
perfiles ⇒ mdev, makedevs y uevent tampoco tienen consumidor.

De los 23 applets que el plan llamaba «el trabajo real» queda: un ADR (awk), una
migración de card (getty → agetty, que ya está en los 7 perfiles), y decidir
nslookup (ningún candidato publica ese nombre; su único llamador es
scripts/drive-netup.py y migrarlo sale más barato que traer BIND).

Y la corrección que me toca: hace dos horas escribí en la salida del vigía, como
advertencia, que «el kernel llama a /sbin/modprobe por call_usermodehelper ⇒ esos
applets salen libres y no lo son». Es plausible, es la forma correcta de razonar,
y es falsa para este producto. La escribí sin medirla, en el mismo commit donde
presumía de haber arreglado dos falsos negativos. Corregida en el script.

NO se recorta ahora: editar RETIRADOS re-hashea busybox y las 24 recetas que lo
declaran build-dep, y 15 de esas 24 siguen en deuda por el recorte del 21/09. El
siguiente recorte junta lo ya decidido y se hace una vez: 6 de kmod + 3 de /dev +
6 alias internos de iproute2 (ipaddr iplink ipneigh iproute iprule iptunnel, que
no son comandos de nadie) = 15 applets, 277 → 262, sin escribir una línea.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sergio
2026-09-22 02:53:58 +00:00
co-authored by Claude Opus 5
parent 8a109400b5
commit 6b33d1a435
2 changed files with 70 additions and 3 deletions
+63
View File
@@ -1297,3 +1297,66 @@ Las dos reglas que quitan ruido son las mismas que crean ceguera, y la diferenci
equivoca cada una. En el modo original —«¿alguien llama a algo que ya retiré?»— un falso positivo
cuesta un minuto y un falso negativo cuesta un boot roto. En este modo pasa igual, así que ahora
busca **tres formas**: nombre desnudo, ruta absoluta y primer elemento de `argv`.
---
# El frente `kmod` no existe: los kernels de takana no tienen módulos (2026-09-22)
**Cómo salió:** al ir a escribir el `kmod` en Rust que este plan pide —la pieza más grande que
quedaba, 6 applets— lo primero fue mirar contra qué módulos probarlo. **No hay ninguno.**
| medida | resultado |
|---|---|
| `.ko` en los artefactos sellados de los 4 kernels | **0** — sólo `boot/bzImage` y el `.config` |
| recetas del corpus que hacen `modules_install` | **0** |
| drivers `=m` en los `.config` sellados | **0** (contra 1809 `=y` en `linux-metal`) |
| `CONFIG_MODULES` en los tres kernels del store | **`# CONFIG_MODULES is not set`** |
| quién enciende `CONFIG_MODULES` en el repo | **nadie** |
Los cuatro kernels son monolíticos por construcción: `compile = "make … bzImage"` y
`install = "cp arch/x86/boot/bzImage /out/boot/"`. Sin `CONFIG_MODULES`, el kernel **ni siquiera
implementa `init_module`/`delete_module`** — un `insmod` escrito en Rust recibiría `ENOSYS`.
> **Los 6 applets de kmod no son trabajo de escritura: son 6 applets a RETIRAR.** Y con ellos se van
> otros 3: `CONFIG_DEVTMPFS_MOUNT=y` hace que el kernel cree y monte `/dev` con sus nodos, no hay
> `CONFIG_UEVENT_HELPER` (o sea que el kernel no llama a ningún helper de hotplug), y `libudev-zero`
> ya viaja en los 8 perfiles. `mdev`, `makedevs` y `uevent` tampoco tienen consumidor.
## Lo que esto le hace a la cuenta del plan
De los **23 applets** que este documento llamó «el trabajo real», queda muy poco:
| pieza | decía | es |
|---|---|---|
| kmod (6) | escribir en Rust | **retirar** — el kernel no tiene módulos |
| gestor de /dev (3) | escribir o decidir | **retirar** — devtmpfs + libudev-zero |
| psmisc (4) | traer | ✅ hecho (3; `killall5` es de sysvinit, lo cubre arje-zero por función) |
| bc (2) | traer | ✅ hecho |
| grep (3) · sed (1) | escribir en Rust | GNU declarado como puente ✅; el Rust nativo sigue siendo deseable, no urgente |
| getty (2) | escribir | **migrar**: `agetty` de util-linux está en los 7 perfiles |
| awk (1) | decidir | sigue siendo un ADR |
| nslookup (1) | traer | **decidir**: ninguno de los candidatos (ldns→`drill`, knot→`kdig`, doggo) publica `nslookup`; el único llamador es `scripts/drive-netup.py` y migrarlo es más barato que traer BIND |
## Y la corrección que me toca a mí
Hace dos horas escribí en la salida de `busybox-vigia.py --uso`, como advertencia:
> «el KERNEL — llama a `/sbin/modprobe` por `call_usermodehelper` … `modprobe lsmod depmod rmmod
> modinfo mdev uevent makedevs` salen «libres» acá y no lo son: es el frente kmod, que es escritura
> pendiente, no un borrado.»
**Es plausible, es la forma correcta de razonar, y es falsa para este producto.** La escribí sin
medirla, en el mismo commit en el que presumía de haber arreglado dos falsos negativos. Corregida en
el script. Es [[la-etiqueta-no-es-el-hecho]] exacta: la advertencia sonaba a experiencia y era una
suposición, y lo que la desarmó fue ir a buscar contra qué probar el código que iba a escribir.
## Qué hacer con los 9 — y por qué NO ahora
Retirarlos es editar `RETIRADOS` en `recipes/busybox.toml`, y eso **re-hashea busybox**. Las 24
recetas que lo declaran build-dep se invalidan, y **15 de esas 24 siguen HOY en deuda por el recorte
del 2026-09-21** (`linux`, `llama-cpp`, `protobuf`, `qdrant`, `valkey`, `zlib-ng`, los firmware…).
Recortar otra vez ahora duplica ese trabajo para la granja.
**El siguiente recorte junta todo lo que ya está decidido y se hace UNA vez:** los 6 de kmod, los 3
de /dev, y los 6 alias internos de iproute2 (`ipaddr iplink ipneigh iproute iprule iptunnel`, que no
son comandos de nadie) — **15 applets, 277 → 262**, sin escribir una línea y sin reemplazar nada.
+7 -3
View File
@@ -193,9 +193,13 @@ def modo_uso():
print()
print('\u26a0 \u00abCandidato\u00bb NO es \u00abretirable\u00bb. Un grep ve a quien INVOCA por nombre, y hay dos clases de')
print(' consumidor que no aparecen NUNCA y que rompen el producto si se les quita el applet:')
print(' \u00b7 el KERNEL — llama a /sbin/modprobe por call_usermodehelper, y al gestor de /dev por')
print(' hotplug. modprobe lsmod depmod rmmod modinfo mdev uevent makedevs salen \u00ablibres\u00bb acá')
print(' y no lo son: es el frente kmod, que es escritura pendiente, no un borrado.')
print(' \u00b7 el KERNEL — puede llamar a un helper de userspace sin que ningún grep lo vea.')
print(' ⚠ Acá NO: los cuatro kernels de takana traen `# CONFIG_MODULES is not set`, CERO')
print(' drivers `=m` y ninguna receta hace `modules_install` (medido 2026-09-22). Así que')
print(' modprobe/lsmod/depmod/rmmod/modinfo NO tienen consumidor, y con DEVTMPFS_MOUNT=y y')
print(' sin UEVENT_HELPER tampoco lo tienen mdev/makedevs/uevent. La advertencia sigue')
print(' valiendo como forma —un helper del kernel no aparece en un grep—, pero en ESTE')
print(' producto esos nueve son retirables, no escritura pendiente.')
print(' \u00b7 el USUARIO de la máquina — clear, reset, vi, traceroute no los invoca ningún guión del')
print(' repo y son la CLI que alguien espera encontrar al entrar por ssh.')
print(' Lo que esta lista sí dice es cuáles no tienen consumidor DENTRO del producto: es el primer')