Skip to content

Commit 28f503c

Browse files
zahclaude
andcommitted
M9.R.39.4: switch autorun unit to self-gating script ExecStart
M9.R.39.2/3's ``ConditionKernelCommandLine=repro.installer.autorun=1`` predicate silently no-op'd in the M9.R.39.3 boot: the kernel cmdline HAS the param (verified via boot log), the unit + Wants symlink ARE staged in the squashfs (verified via unsquashfs -ll), yet no ``Starting reproos-installer-autorun.service`` line appears in the boot log. Replace the systemd-side gate with a wrapper script ExecStart that self-checks /proc/cmdline + ``REPROOS-INSTALLER-AUTORUN-{BEGIN,SKIP, END}`` markers to the console journal, and unconditionally poweroffs at the end (whether the install ran or got skipped). The unit now runs AFTER multi-user.target with no ConditionKernel predicate, so the path is: boot -> getty.target -> login prompt -> reproos-installer-autorun .service kicks in -> wrapper checks cmdline -> install or skip -> poweroff -> QEMU exits -> host driver wait completes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 01e8a11 commit 28f503c

1 file changed

Lines changed: 58 additions & 15 deletions

File tree

recipes/reproos-iso/scripts/stage-de-rootfs.sh

Lines changed: 58 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -591,35 +591,78 @@ EOF
591591
# without needing a timeout kill that could interrupt the diag-persist
592592
# dd to /dev/vdb.
593593
mkdir -p "$STAGE_DIR/etc/systemd/system"
594+
# M9.R.39.4 — drop the M9.R.39.2 ConditionKernelCommandLine approach
595+
# (the condition's match against /proc/cmdline silently no-op'd in the
596+
# M9.R.39.3 boot — no "Starting" line ever appeared in the boot log).
597+
# Replace with a self-gating ExecStart wrapper script that parses
598+
# /proc/cmdline at run time and skips the install body when the
599+
# ``repro.installer.autorun=1`` token is absent. systemd doesn't need
600+
# to evaluate the gate; the script handles it.
601+
#
602+
# The wrapper also re-exports a small env tail so the launcher's
603+
# inner ``exec env LD_LIBRARY_PATH=...`` chain stays intact, and
604+
# unconditionally poweroffs at the end so QEMU exits and the host
605+
# driver's wait completes.
606+
mkdir -p "$STAGE_DIR/usr/local/sbin"
607+
cat > "$STAGE_DIR/usr/local/sbin/reproos-installer-autorun.sh" <<'EOF'
608+
#!/bin/sh
609+
# M9.R.39.4 — installer autorun wrapper invoked from the
610+
# reproos-installer-autorun.service systemd unit at boot.
611+
#
612+
# Self-gates on /proc/cmdline -> only runs the installer if
613+
# ``repro.installer.autorun=1`` is present. Always poweroffs at the
614+
# end so QEMU exits cleanly + the host driver's wait completes.
615+
set -u
616+
617+
echo "=== REPROOS-INSTALLER-AUTORUN-BEGIN ===" 1>&2
618+
echo "uptime: $(cat /proc/uptime 2>/dev/null)" 1>&2
619+
echo "cmdline: $(cat /proc/cmdline 2>/dev/null)" 1>&2
620+
621+
if ! grep -qE '(^| )repro\.installer\.autorun=1( |$)' /proc/cmdline 2>/dev/null; then
622+
echo "=== REPROOS-INSTALLER-AUTORUN-SKIP (cmdline lacks repro.installer.autorun=1) ===" 1>&2
623+
exit 0
624+
fi
625+
626+
export QT_QPA_PLATFORM=offscreen
627+
export REPRO_INSTALLER_DIAG=1
628+
629+
# Run the launcher synchronously.
630+
/usr/bin/reproos-installer-launcher.sh --automated /etc/reproos/auto-config.toml
631+
rc=$?
632+
633+
echo "=== REPROOS-INSTALLER-AUTORUN-END RC=$rc ===" 1>&2
634+
635+
# Poweroff so QEMU exits + driver wait completes. We do it from the
636+
# wrapper (not ExecStopPost) so the systemd unit's life-cycle is
637+
# uncomplicated.
638+
sync
639+
sync
640+
/sbin/poweroff -f
641+
exit "$rc"
642+
EOF
643+
chmod 0755 "$STAGE_DIR/usr/local/sbin/reproos-installer-autorun.sh"
644+
594645
cat > "$STAGE_DIR/etc/systemd/system/reproos-installer-autorun.service" <<'EOF'
595646
[Unit]
596-
Description=ReproOS Installer auto-run (M9.R.39.2 diagnostic boot path)
597-
ConditionKernelCommandLine=repro.installer.autorun=1
598-
DefaultDependencies=no
599-
After=local-fs.target sysinit.target
600-
Before=multi-user.target getty.target
647+
Description=ReproOS Installer auto-run (M9.R.39.4 diagnostic boot path)
648+
After=local-fs.target sysinit.target multi-user.target
649+
Wants=multi-user.target
601650
602651
[Service]
603652
Type=oneshot
604653
RemainAfterExit=yes
605654
StandardOutput=journal+console
606655
StandardError=journal+console
607-
Environment=QT_QPA_PLATFORM=offscreen
608-
Environment=REPRO_INSTALLER_DIAG=1
609-
ExecStart=/bin/sh -c 'echo === REPROOS-INSTALLER-AUTORUN-BEGIN ===; /usr/bin/reproos-installer-launcher.sh --automated /etc/reproos/auto-config.toml; echo === REPROOS-INSTALLER-AUTORUN-END RC=$? ==='
610-
# Always poweroff after the run so the host driver can detect end-of-life
611-
# via QEMU exit; even on SIGABRT we want a clean shutdown so the
612-
# /dev/vdb diag dd reaches stable storage.
613-
ExecStopPost=/bin/sh -c 'sync; sync; /sbin/poweroff -f'
656+
ExecStart=/usr/local/sbin/reproos-installer-autorun.sh
614657
615658
[Install]
616659
WantedBy=multi-user.target
617660
EOF
618661

619662
# Enable the unit via a symlink under multi-user.target.wants/ so
620-
# systemd activates it during boot (when the kernel-cmdline condition
621-
# is satisfied). Without the explicit Wants link the unit is staged
622-
# but never triggered.
663+
# systemd activates it during boot. The script ExecStart self-gates
664+
# on the kernel cmdline param, so the symlink is unconditional —
665+
# a non-investigator boot just sees the script print SKIP and exit.
623666
mkdir -p "$STAGE_DIR/etc/systemd/system/multi-user.target.wants"
624667
ln -sf /etc/systemd/system/reproos-installer-autorun.service \
625668
"$STAGE_DIR/etc/systemd/system/multi-user.target.wants/reproos-installer-autorun.service"

0 commit comments

Comments
 (0)