Skip to content

initrd-flash: propagate the device's final status instead of always returning 0 - #355

Open
WarrDoge wants to merge 1 commit into
avocado-linux:scarthgapfrom
WarrDoge:initrd-flash-propagate-device-status
Open

initrd-flash: propagate the device's final status instead of always returning 0#355
WarrDoge wants to merge 1 commit into
avocado-linux:scarthgapfrom
WarrDoge:initrd-flash-propagate-device-status

Conversation

@WarrDoge

@WarrDoge WarrDoge commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

get_final_status() in meta-avocado-nvidia/recipes-bsp/tegra-binaries/tegra-helper-scripts/initrd-flash.sh reads the status the device wrote, prints it, and then returns 0 regardless of what it said:

973:    final_status=$(cat $mnt/flashpkg/status)
        ...
989:    echo "Final status: $final_status"
990:    return 0

final_status is never compared to anything. The caller at :1081 only tests whether get_final_status itself failed, so a device that wrote FAILED produces Successfully finished at ... (:1087) and exit 0 (:1117). stone provision then prints [SUCCESS] Provision completed. — stone's own Rust propagates correctly, so the result is lost entirely here.

This PR compares the value and returns non-zero when it is not SUCCESS. The message goes to stderr so it survives the 2>&1 | tee the caller wraps the call in.

How it showed up

Flashing a Jetson Orin Nano devkit: an out-of-tree QSPI driver was rejected on the device (MODULE_SIG_FORCE, module shipped unsigned), so there was no /dev/mtd0, the device wrote bootloader-status=FAILED, and the board was dark afterwards. The host printed [SUCCESS] and exited 0. The real result was only visible by reading deploy/stone/_build/tegraflash/device-logs-*/bootloader.log by hand — which one only thinks to do after distrusting the exit code.

The cost is not the failed flash, it is that a silent success trains you to trust the wrong signal, and CI cannot tell a flashed board from a bricked one.

Notes

The same return 0 is in meta-tegra's copy of this script, so this is inherited rather than introduced here — I am sending it to the layer whose copy I build against, and it applies equally upstream if you would rather it went there first.

Separately, and deliberately not in this PR: this fork appears to have dropped the early-failure detection that meta-tegra still has. In meta-tegra, early_final_status is set to 1 at the "got flashpkg when expecting $name" branch, which is how an early device-side failure is distinguished. In this copy that branch is absent and early_final_status is only ever 0 (:51), so the two if [ $early_final_status -eq 0 ] guards at :1061 and :1069 are always true — dead conditionals wrapped around a live exit 1. Harmless today, but they read as live error handling and are not, and anyone "fixing" them by making the variable settable would change control flow in a way nothing currently tests. Happy to file that separately or fold in a restoration if you would prefer it here.

Testing

Ran against the same hardware after the change; a successful flash still reports success and exits 0. I have not synthesised a device-side failure since the original one, so the failure branch is reasoned from the code rather than re-triggered — say the word if you would like me to force one before merging.

get_final_status() reads the status the device wrote, prints it, and then
returns 0 whatever it said. The caller only tests whether the function itself
failed, so a device that reported FAILED still produces "Successfully finished"
and exit 0 - and `stone provision` reports [SUCCESS] over a board that did not
flash.

Compare the value and return non-zero when it is not SUCCESS. The message goes
to stderr so it survives the `2>&1 | tee` the caller wraps this in.

Seen on a Jetson Orin Nano devkit: an out-of-tree QSPI driver was rejected on
the device, there was no /dev/mtd0, the device wrote bootloader-status=FAILED,
and the host reported success over a board that would not boot. The failure was
only visible by reading device-logs-*/bootloader.log by hand.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant