diff --git a/docs/plan-botar-busybox.md b/docs/plan-botar-busybox.md index 57234d36..52236dfa 100644 --- a/docs/plan-botar-busybox.md +++ b/docs/plan-botar-busybox.md @@ -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. diff --git a/scripts/busybox-vigia.py b/scripts/busybox-vigia.py index 4291dff5..0801343d 100755 --- a/scripts/busybox-vigia.py +++ b/scripts/busybox-vigia.py @@ -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')