kent

kent / meta-brintos public Read only

0
0

stage-machine.sh rewrites /etc/inittab unconditionally, dropping every ::sysinit line the image staged #1

Open dmitry opened this issue · 0 comments
D dmitry commented

Summary

scripts/stage-machine.sh step 3 rewrites /etc/inittab unconditionally, so anything the image recipe wrote there is discarded on the way to the deploy-ready machine dir. The rootfs bitbake produces is correct; the machine that boots is not.

Two ::sysinit lines are lost on core-image-brintos-emcraft (glibc), observed on one build — the script's own input vs output:

/etc/inittab
rootfs.tar.zst (bitbake output = script input) 4 lines
machine-stage (script output = what deploys) 2 lines
# present in the tarball, absent from machine-stage:
::sysinit:/bin/mount -t tmpfs -o mode=1777,nosuid,nodev tmpfs /tmp
::sysinit:/usr/sbin/run-postinsts

Impact

  • The tmpfs /tmp mount never reaches a deployed machine. core-image-minimal-brintos.bb adds it with a comment stating it is required so an anonymously-booted session (non-root, read-only cloud virtio-fs root) has a writable scratch dir — "without it any tool/self-test that writes /tmp fails EACCES". This affects every machine staged by this script, not one image.
  • First-boot maintainer scripts cannot run. run-postinsts is hooked into ::sysinit so deferred pkg_postinst_ontarget scriptlets execute on first boot (there is no wasm32 qemu-user to run them at do_rootfs). With the line stripped the runner never fires, however correct the rootfs is.

Reproduction

Build any *-brintos image whose recipe customises the inittab, then compare the tarball with the staged dir:

tar --zstd -xOf <image>.rootfs.tar.zst ./etc/inittab   # 4 lines
cat <machine-stage>/etc/inittab                        # 2 lines

Root cause

The script's header says it "Encodes the 2026-07-03 bring-up findings; fold into ROOTFS_POSTPROCESS_COMMAND eventually." That fold has since happened — brintos_fixup_rootfs in core-image-minimal-brintos.bb performs the same steps 1-4 (relativize symlinks, real /init, substrate-minimal inittab, empty profile) and adds ::sysinit lines of its own. So for a *-brintos image the script's steps are redundant, and step 3 is actively lossy: the recipe writes a richer inittab than the one that overwrites it. Steps 1, 2 and 4 are idempotent against the recipe; only step 3 destroys information.

Proposed fix

Write the fallback inittab only when the image staged none of its own, keyed on the ::respawn line both paths emit. An image carrying brintos_fixup_rootfs keeps its own; any other image gets the previous content unchanged.

Branch: fix/stage-machine-keep-image-inittab Commit: e5ea42d

-# 3. Substrate-minimal inittab (setsid/cttyhack hang on unimplemented syscalls).
-printf "::respawn:-/bin/sh\n::ctrlaltdel:/bin/umount -a -r\n" > "$STAGE/etc/inittab"
+# 3. Substrate-minimal inittab (setsid/cttyhack hang on unimplemented syscalls),
+# but only when the image did not already stage one. The *-brintos images fold
+# this into brintos_fixup_rootfs and add ::sysinit lines of their own -- the
+# tmpfs /tmp mount, the run-postinsts first-boot runner -- which an
+# unconditional rewrite here silently drops on the way to the machine dir.
+if ! grep -qs '^::respawn:-/bin/sh$' "$STAGE/etc/inittab"; then
+    printf "::respawn:-/bin/sh\n::ctrlaltdel:/bin/umount -a -r\n" > "$STAGE/etc/inittab"
+fi

Verified on core-image-brintos-emcraft (glibc): with the fix the staged inittab keeps all four lines, and a browser boot of the deployed machine runs both the tmpfs mount and run-postinsts (Setting up brintos-postinst-canary (1.0-r0) ...).

Proposed fix targets kent/meta-brintos only — no distro submodule pins moved. All distros share one lineage, so pin bumps are coordinated on merge, not per-engineer.