instalador en RAM VERDE en QEMU: dos fallos más, y los dos eran del verificador
Segunda y tercera corrida. Ninguno de los dos era del instalador: eran del código que comprueba que el instalador hizo bien su trabajo, que es el que menos se mira y el que más caro sale cuando miente. 4) EL GUARDIÁN ACUSÓ AL INOCENTE. La verificación post-mke2fs usaba `blkid -s LABEL -o value`, que es de util-linux y **busybox IGNORA**: devuelve la línea entera. El formateo había salido perfecto y el instalador abortó igual, con un mensaje que mostraba la label correcta DENTRO del texto de «no quedó con LABEL». Ahora la label se extrae con sed y funciona con los dos blkid. 5) MTOOLS SE COLGÓ ESPERANDO UNA RESPUESTA. Sobre /dev/vda1 el instalador se detuvo para siempre justo tras imprimir el espacio libre, sin una línea más — y colgado es indistinguible de lento, que en un instalador se lee como «se murió». Dos defensas: MTOOLS_SKIP_CHECK=1 (el chequeo de geometría es lo que dispara la pregunta) y `< /dev/null` en cada invocación, para que una pregunta que igual aparezca FALLE en vez de esperar. Lo mismo para el instalador entero en el /init: nada ahí debe leer del teclado. VERDE de punta a punta en QEMU, sobre un disco con una «Artix vieja» en p2, datos del usuario en p3 y una ESP con Windows simulado. Verificado por dd y hashes, no por la salida del propio instalador: · p3 (datos del usuario) sha256 IDÉNTICO antes y después · p2 (la vieja raíz) LABEL=hammer-root en el superbloque ⇒ reemplazada · \EFI\takana\takanax64.efi = bzImage exacto · \EFI\BOOT\BOOTX64.EFI intacto (es del vecino) · \EFI\Microsoft\ intacto · tabla de particiones 3 entradas, sin cambios Lo único que falta del camino completo es el salto en sí (`takana kernel kexec --jump`, ADR 0017): el kernel de esta caja no trae CONFIG_KEXEC_FILE, así que ahí no se puede probar. Lo que sí está probado es lo que pasa DESPUÉS del salto, que es todo lo demás. ⚠ Y una lección del propio commit anterior: el mensaje llevaba `takana kernel kexec --jump` entre backticks dentro de comillas dobles, así que la shell lo EJECUTÓ y el texto llegó vacío al log. Mismo patrón que el heredoc sin comillas que ya está anotado. Los mensajes van por `-F -` con heredoc CITADO. 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.
2 archivos · +31 −13
diff --git a/scripts/instalador-initramfs.sh b/scripts/instalador-initramfs.sh
index 6616f203..d8d89a16 100755
--- a/scripts/instalador-initramfs.sh
+++ b/scripts/instalador-initramfs.sh
@@ -154,7 +154,9 @@ export STAGE=/payload/stage STAGE_LISTO=1 KERNEL=/payload/bzImage HAMMER=/bin/ta
# 2026-09-23, y es el modo de fallo más caro posible: el usuario reinicia confiando y se queda sin
# sistema. El estado del instalador se guarda aparte y se lee después; el pipe ya no decide nada.
# shellcheck disable=SC2086
-{ sh /instalador/takana-install-partition.sh $ARGS --yes; echo $? > /rc; } 2>&1 | tee /dev/tty0 > /dev/ttyS0
+# `< /dev/null`: nada de esto debe leer del teclado —las confirmaciones ya van por `--yes`— y si
+# algo lo intenta tiene que FALLAR, no quedarse esperando en una consola que nadie está mirando.
+{ sh /instalador/takana-install-partition.sh $ARGS --yes < /dev/null; echo $? > /rc; } 2>&1 | tee /dev/tty0 > /dev/ttyS0
if [ "$(cat /rc 2>/dev/null || echo 1)" = "0" ]; then
log "TAKANA-INSTALADOR-OK: instalado. Reiniciando en 10 s (sacá el medio si lo hubiera)."
sync; sleep 10; reboot -f
diff --git a/scripts/takana-install-partition.sh b/scripts/takana-install-partition.sh
index dc6ce57e..f776b141 100755
--- a/scripts/takana-install-partition.sh
+++ b/scripts/takana-install-partition.sh
@@ -335,7 +335,14 @@ else
fi
# Y no se da por hecho: se mira. Regla 3 del CLAUDE.md — un ausente falla ruidosamente, un vacío
# llega hasta el final diciendo que todo fue bien. Acá el vacío sería un destino sin filesystem.
-_lbl_post=$(blkid -s LABEL -o value "$DEST" 2>/dev/null || true)
+# ⚠ La verificación tiene que funcionar con LOS DOS `blkid`, y la primera versión no lo hacía:
+# `-s LABEL -o value` es de util-linux y **busybox lo ignora**, devolviendo la línea entera
+# (`/dev/vda2: LABEL="hammer-root" UUID=…`). Resultado medido en QEMU: el formateo había salido
+# PERFECTO y el guardián abortó igual, con un mensaje que mostraba la label correcta dentro del
+# texto de «no quedó con LABEL». Tercer caso hoy del mismo patrón: un chequeo que valida algo
+# distinto de lo que cree validar acusa al inocente, y un guardián así se desactiva a la semana.
+_lbl_post=$(blkid "$DEST" 2>/dev/null | sed -n 's/.*LABEL="\([^"]*\)".*/\1/p')
+[ -n "$_lbl_post" ] || _lbl_post=$(blkid -s LABEL -o value "$DEST" 2>/dev/null || true)
[ "$_lbl_post" = "hammer-root" ] || {
echo "takana-install-partition: $DEST NO quedó con LABEL=hammer-root (blkid dice '${_lbl_post:-nada}')." >&2
echo " El formateo no se completó: no sigo." >&2; exit 1; }
@@ -343,13 +350,22 @@ echo " ✓ $DEST formateada y poblada (LABEL=hammer-root verificada)"
# ── 3) La ESP: sólo nuestra carpeta de vendor, con mtools y SIN montar ─────────────────────────
if [ -n "$ESP" ]; then
- "$MDIR" -i "$ESP" :: >/dev/null 2>&1 || { echo "takana-install-partition: $ESP no parece FAT (¿es la ESP?)" >&2; exit 1; }
+ # ⚠ **mtools puede QUEDARSE ESPERANDO UNA RESPUESTA, y colgado es indistinguible de lento.**
+ # Medido en QEMU el 2026-09-23: sobre `/dev/vda1` el instalador se detuvo para siempre justo
+ # después de imprimir el espacio libre, sin una línea más. Dos defensas, porque una sola tapa el
+ # síntoma sin quitar la causa:
+ # · `MTOOLS_SKIP_CHECK=1` desactiva el chequeo de geometría, que es lo que hace preguntar
+ # cuando el device no se parece a un disquete;
+ # · `< /dev/null` en cada invocación, para que una pregunta que igual aparezca FALLE en vez de
+ # esperar. Un error se lee; un cuelgue en un instalador parece un sistema muerto.
+ export MTOOLS_SKIP_CHECK=1
+ "$MDIR" -i "$ESP" :: >/dev/null 2>&1 < /dev/null || { echo "takana-install-partition: $ESP no parece FAT (¿es la ESP?)" >&2; exit 1; }
# Guardián de capacidad: una ESP de fábrica son 100 MiB y Windows ya vive ahí. El margen se
# comprueba ANTES, con los números a la vista, no como un «disk full» a mitad de copiar.
# ⚠ `mdir` imprime el espacio libre con SEPARADOR DE MILES en espacios («60 056 064 bytes
# free»), así que tomar `$1` devuelve **60** y el guardián aborta una instalación perfectamente
# posible. Medido en la primera corrida de este script. Hay que juntar los dígitos de la línea.
- _free=$("$MDIR" -i "$ESP" :: 2>/dev/null | awk '/bytes free/ {l=$0; sub(/ bytes free.*/,"",l); gsub(/[^0-9]/,"",l); print l}' | tail -1)
+ _free=$("$MDIR" -i "$ESP" :: 2>/dev/null < /dev/null | awk '/bytes free/ {l=$0; sub(/ bytes free.*/,"",l); gsub(/[^0-9]/,"",l); print l}' | tail -1)
_need=$(( $(wc -c < "$KERNEL") + $(wc -c < "$IRD") ))
[ -n "${_free:-}" ] && [ "$_free" -lt "$_need" ] && {
echo "takana-install-partition: la ESP tiene ${_free}B libres y hacen falta ${_need}B." >&2
@@ -375,27 +391,27 @@ if [ -n "$ESP" ]; then
_free="$_cap"
fi
echo "==> ESP $ESP: \\EFI\\takana\\ (${_need}B sobre ${_free:-?}B libres)"
- "$MMD" -i "$ESP" ::/EFI 2>/dev/null || true
- "$MMD" -i "$ESP" ::/EFI/takana 2>/dev/null || true
- "$MCOPY" -o -i "$ESP" "$KERNEL" ::/EFI/takana/takanax64.efi
- "$MCOPY" -o -i "$ESP" "$IRD" ::/initramfs.cpio.gz
+ "$MMD" -i "$ESP" ::/EFI 2>/dev/null < /dev/null || true
+ "$MMD" -i "$ESP" ::/EFI/takana 2>/dev/null < /dev/null || true
+ "$MCOPY" -o -i "$ESP" "$KERNEL" ::/EFI/takana/takanax64.efi < /dev/null
+ "$MCOPY" -o -i "$ESP" "$IRD" ::/initramfs.cpio.gz < /dev/null
# La ruta fallback es tierra de nadie: si YA hay algo, es de otro sistema y no se pisa sin que
# el usuario lo pida. Si no hay nada, ocuparla es gratis y salva el caso «el firmware ignora la
# entrada NVRAM», que es el modo de fallo más común y el más difícil de diagnosticar.
- if "$MDIR" -i "$ESP" ::/EFI/BOOT/BOOTX64.EFI >/dev/null 2>&1; then
+ if "$MDIR" -i "$ESP" ::/EFI/BOOT/BOOTX64.EFI >/dev/null 2>&1 < /dev/null; then
if [ -n "$CLAIM_FALLBACK" ]; then
- "$MCOPY" -o -i "$ESP" "$KERNEL" ::/EFI/BOOT/BOOTX64.EFI
+ "$MCOPY" -o -i "$ESP" "$KERNEL" ::/EFI/BOOT/BOOTX64.EFI < /dev/null
echo " ! \\EFI\\BOOT\\BOOTX64.EFI PISADO (--claim-fallback)"
else
echo " · \\EFI\\BOOT\\BOOTX64.EFI ya existe y es de otro: NO se toca (--claim-fallback para pisarlo)"
fi
else
- "$MMD" -i "$ESP" ::/EFI/BOOT 2>/dev/null || true
- "$MCOPY" -o -i "$ESP" "$KERNEL" ::/EFI/BOOT/BOOTX64.EFI
+ "$MMD" -i "$ESP" ::/EFI/BOOT 2>/dev/null < /dev/null || true
+ "$MCOPY" -o -i "$ESP" "$KERNEL" ::/EFI/BOOT/BOOTX64.EFI < /dev/null
echo " + \\EFI\\BOOT\\BOOTX64.EFI estaba libre ⇒ ocupada (arranca sin depender de la NVRAM)"
fi
for _p in ::/EFI/takana/takanax64.efi ::/initramfs.cpio.gz; do
- "$MDIR" -i "$ESP" "$_p" >/dev/null 2>&1 || { echo "takana-install-partition: falta $_p en la ESP" >&2; exit 1; }
+ "$MDIR" -i "$ESP" "$_p" >/dev/null 2>&1 < /dev/null || { echo "takana-install-partition: falta $_p en la ESP" >&2; exit 1; }
done
echo " ✓ ESP poblada y verificada (sin montarla)"
else