install-image: la guarda del init estaba INVERTIDA, y el staging no podía cruzar el montaje
Dos cosas encontradas armando la primera imagen del `perfil.servidor` (SDD 28 §1b). **1. `[ -e "$ROOTFS/sbin/init" ]` rechazaba el rootfs CORRECTO y aceptaba el equivocado.** `-e` sigue el symlink y lo resuelve contra el HOST. El `/sbin/init` del product-rootfs es un symlink ABSOLUTO a `/usr/bin/arje-zero`, que en el host no existe ⇒ la guarda daba falso. Y al revés: un rootfs cuyo init es `../bin/busybox` —symlink RELATIVO, que sí resuelve dentro del árbol— la pasaba sin chistar. O sea que la única guarda que separaba «esto arranca takana» de «esto arranca otra cosa» estaba exactamente al revés. Ahora acepta `-L`, y se probó en los dos sentidos: acepta el symlink absoluto a arje-zero, sigue rechazando un directorio sin init. Esto no es teórico: hidratar `perfil.servidor` sobre el product-rootfs **pisa `/sbin/init`** — busybox entra en la clausura y su symlink gana por llegar después—. La imagen habría arrancado perfecto con el init de busybox en vez de arje-zero, que es peor que no arrancar. Se restaura el symlink al ensamblar y el cmdline lleva `init=/usr/bin/arje-zero` explícito, por las dos puntas. **2. `STAGE` estaba cableado a `work/.install-stage`.** El staging HARDLINKEA desde `$ROOTFS`, y un hardlink no cruza un montaje aunque sea el mismo disco. Con el layout normal de este repo —`store` y `work/out` son bind-mounts de /dev/sdb, `work/` está en /dev/sdc— el rootfs vive del otro lado y `cp -al` muere con EXDEV fichero por fichero. Ahora es env, documentado en la cabecera. De paso: el fichero no tenía bit de ejecución (100644) mientras sus siete hermanos son 100755, así que su propio ejemplo de uso `./scripts/install-image.sh` no funcionaba. Venía de antes; corregido. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RomoxEGZUhaT4pob1QSX5x
This commit is contained in:
Regular → Executable
+13
-2
@@ -24,6 +24,8 @@
|
||||
#
|
||||
# Variables:
|
||||
# ROOTFS dir rootfs a empaquetar (default work/builder-rootfs)
|
||||
# STAGE dir de staging (default work/.install-stage) — DEBE estar en el
|
||||
# mismo montaje que ROOTFS: el staging hardlinkea y un hardlink no cruza montajes
|
||||
# PREALLOC 1 ⇒ trata IMG como target pre-dimensionado in-place (no trunca; prueba el camino device)
|
||||
# KERNEL bzImage a embeber en /boot (default el del store: store/*-linux/boot/bzImage)
|
||||
# IMG imagen de salida (default work/takana-install.img)
|
||||
@@ -47,7 +49,12 @@ KERNEL="${KERNEL:-$(ls store/*-linux/boot/bzImage 2>/dev/null | head -1)}"
|
||||
GRUB_LIB="${GRUB_LIB:-/usr/lib/grub/i386-pc}"
|
||||
|
||||
[ -d "$ROOTFS" ] || { echo "no existe ROOTFS: $ROOTFS (corré selfhost-verify para armar el builder)" >&2; exit 1; }
|
||||
[ -e "$ROOTFS/sbin/init" ] || { echo "ROOTFS sin /sbin/init (arje-zero)" >&2; exit 1; }
|
||||
# `-e` sigue el symlink y lo resuelve contra el HOST, no contra el rootfs. El `/sbin/init` del
|
||||
# product-rootfs es un symlink ABSOLUTO a `/usr/bin/arje-zero`, que en el host no existe ⇒ `-e` da
|
||||
# falso y esta guarda rechazaba el rootfs CORRECTO. Peor: un rootfs con el init equivocado
|
||||
# (`../bin/busybox`, symlink RELATIVO que sí resuelve dentro del árbol) la pasaba sin chistar.
|
||||
# O sea que la guarda estaba exactamente invertida. `-L` acepta el symlink por lo que es.
|
||||
[ -e "$ROOTFS/sbin/init" ] || [ -L "$ROOTFS/sbin/init" ] || { echo "ROOTFS sin /sbin/init (arje-zero)" >&2; exit 1; }
|
||||
[ -n "$KERNEL" ] && [ -r "$KERNEL" ] || { echo "no encuentro el kernel a embeber (set KERNEL=<bzImage>)" >&2; exit 1; }
|
||||
[ -d "$GRUB_LIB" ] && [ -r "$GRUB_LIB/boot.img" ] || { echo "faltan los módulos GRUB i386-pc en $GRUB_LIB" >&2; exit 1; }
|
||||
for t in sfdisk mke2fs grub-mkimage grub-bios-setup; do
|
||||
@@ -55,7 +62,11 @@ for t in sfdisk mke2fs grub-mkimage grub-bios-setup; do
|
||||
done
|
||||
unshare -r true 2>/dev/null || { echo "se requiere 'unshare -r' (ficheros root-owned sin sudo)" >&2; exit 1; }
|
||||
|
||||
STAGE="work/.install-stage"
|
||||
# El staging ENLAZA (hardlink) desde $ROOTFS, y un hardlink no cruza un montaje aunque sea el mismo
|
||||
# disco. Con el store en un volumen aparte —el layout normal de este repo: `store` y `work/out` son
|
||||
# bind-mounts de /dev/sdb y `work/` está en /dev/sdc— el rootfs vive del otro lado y `cp -al` muere
|
||||
# con EXDEV fichero por fichero. Por eso es env: ponelo bajo el MISMO montaje que $ROOTFS.
|
||||
STAGE="${STAGE:-work/.install-stage}"
|
||||
rm -rf "$STAGE"
|
||||
mkdir -p "$STAGE"
|
||||
ROOT_TREE="$STAGE/root"
|
||||
|
||||
Reference in New Issue
Block a user