Repository navigation
sysupgrade: hand PID 1 off for every rootfs write, not only on UBI - #2648
Merged
Merged
Conversation
On NOR a squashfs rootfs can be rewritten while mounted, so the PID 1 hand-off was kept for UBI, where it is the only way. But busybox init then runs from the old root through the whole erase, and free_resources has dropped the page cache: when init next runs -- to reap one of the old root's processes dying of SIGBUS -- it faults its own text in from flash being wiped, takes SIGBUS itself, and "Attempted to kill init!" reboots the camera with its rootfs half written. A lab XM510 (18 MB) did that in three runs of four (#2647); the free-RAM floor did not catch it, since what it counts as reclaimable is exactly those pages, and on a kernel without MemAvailable it does not run at all. want_handoff() makes any rootfs write hand PID 1 to the RAM root where it can: the image's inittab has ::restart:/sbin/init, a RAM root can be built, and the images are not behind the old root. Unlike need_handoff it is a preference: without any of those the run flashes as it did before.
widgetii
requested review from
cronyx,
flyrouter and
viktorxda
as code owners
October 21, 2026 04:32
PR Summary by QodoHand PID 1 to RAM before eligible NOR rootfs writes
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
Code Review by Qodo🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)
Great, no issues found!Qodo reviewed your code and found no material issues that require reviewTip of the day💡 Did you know, you can start a comment with 'qodo' or '@qodo' to chat about any finding |
This was referenced Oct 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
#2647.
sysupgrade --rootfson a low-memory camera kills PID 1 in the middle of the erase and leaves the rootfs half-written. A lab XM510 (mem=18M) did this in 3 of 4 runs and then boot-looped. Without a UART it would be bricked.Cause. On NOR the squashfs rootfs can be rewritten while mounted, so the PID 1 hand-off was used only on UBI, where it is required. busybox init therefore keeps running from the old root through the whole erase.
free_resourceshas already dropped the page cache. When init next runs (to reap one of the old root's processes dying of SIGBUS), it faults its own text in from flash being wiped, takes SIGBUS, and the kernel panics.The free-RAM floor (
check_flash_ram) doesn't cover this, for two reasons:MemAvailable(before 3.14, including XM510, XM530 and hi3516cv100) it doesn't run at all.Change
want_handoff()makes any run that rewrites the rootfs hand PID 1 to the RAM root (busybox init::restart:/sbin/init), as UBI layouts already do. Before the first write, init execs into RAM, every process on the old root is killed, and the old root is released (umount -l /mnt). Nothing that can fault in from the erased partition is left running.Unlike
need_handoff, this is a preference, not a requirement. The run flashes exactly as before, from a plain RAM root or in place, in any of these cases:::restart:entry;--no_ramfs, nopivot_root, staging fails);Kernel-only writes are unchanged and are flashed in place.
Trade-off: a hand-off ends SSH and the WebUI session, so a WebUI upgrade loses majestic's live progress bar. Progress goes to the HTTP log on port 80 (
curl -sN http://<camera>/) and to the serial console, as on UBI cameras today.Hardware tested on
xm510_lite, kernel 3.0.101, 15.6 MBMemTotal).xm530_lite).Both run firmware master plus OpenIPC/linux#130 and majestic#1098. This branch's
sysupgrade, comment-stripped as the build ships it, was placed on the camera:/tmp.Evidence
Before (XM510,
sysupgrade -z -f --rootfs=/tmp/rootfs.squashfs.xm510), 3 of 4 runs:Each time the board was recovered through U-Boot TFTP, with a CRC32 read-back.
After (XM510, same command, three runs in a row, UART captured):
XM550, kernel + rootfs:
Tests:
test_sysupgrade.sh: 323 checks pass, 5 of them new:::restart:it still pivots into a plain RAM root;/tmpisn't handed off;The first of these fails on master.
STRICT=1 test_shell_parse.shandtest_strip_shell_comments.sh: clean.Scope
general/package/all-patches/linux/(those go to OpenIPC/linux)general/overlay/or in a sharedload_<vendor>script hardcodes a value specific to my boardLD_PRELOAD, and no binaries that cannot be rebuilt from source