Repository navigation
sysupgrade: unmount the old root and add a ubi-aware write path so ubifs devices can be upgraded #2253
Description
Follow-up to #239, which asked for pivot_root + chroot in sysupgrade so that ubifs devices could be updated. The mechanism landed in #2252; the ubifs half did not. Splitting the remainder out so it is stated precisely rather than sitting inside a four-year-old issue that is now mostly done.
What #2252 already gives you
enter_ramfs stages busybox, its loader and libraries and the script into a tmpfs, moves /dev, /proc and /tmp across, then pivot_root + chroot + re-exec. After that, nothing the flash phase runs depends on the old rootfs — which is the hard prerequisite for touching the volume it lives on.
Verified on gk7205v200 (34 MB, musl) and hi3516av300 (754 MB, glibc): after the pivot / is tmpfs, busybox is on tmpfs, and every tool the flash phase uses resolves and runs with the page cache dropped.
What is still missing
1. The old root is deliberately still mounted. enter_ramfs leaves it at /mnt on purpose — the MTD partitions are reached through /dev, so nothing needed it unmounted, and keeping it costs nothing today. For ubifs it is the whole problem: you cannot rewrite a mounted volume.
2. There is no ubi-aware write path. do_update_rootfs is flashcp -v $image $(get_device rootfs), which writes an MTD partition raw. A ubifs volume needs ubiupdatevol (or detach → ubiformat/ubiattach → ubimkvol), not a raw partition write.
3. Nothing detects a ubifs rootfs. get_system_info records flash_type as nor/nand via ipcinfo -F, and root_on_flash from /proc/cmdline, but nothing distinguishes root=ubi0:rootfs from a squashfs-on-MTD root and routes to a different writer.
The part that needs a decision, not just code
pivot_root moves the mount namespace, but other processes keep their mappings on the old rootfs. dropbear, and under --web majestic, are still executing from it, so a plain umount /mnt will return EBUSY.
That collides head-on with a property #2252 relies on: --web deliberately keeps majestic alive so it can go on streaming the upgrade log over /ws/upgrade (its tail fd and the websocket survive the pivot, since moving a mount does not disturb open fds). Unmounting the old root means killing it, and with it the user's only view of the flash.
Options, roughly:
umount -l /mnt(lazy) — detaches the tree so ubi operations can proceed while existing mappings drain. Least disruptive; needs checking that it actually frees the ubi volume rather than just hiding the mount.- Kill everything holding the old root before unmounting, and accept that the WebUI log stops at that point (the browser already handles the socket closing).
- Only unmount on the ubifs path, leaving the MTD path exactly as it is now.
The third is probably the right default: it keeps a working, tested path working, and confines the risk to devices that cannot be upgraded at all today.
Grounding
- busybox already ships the tooling:
CONFIG_UBIATTACH,UBIDETACH,UBIMKVOL,UBIRMVOL,UBIUPDATEVOL,UBIRENAMEare all=yingeneral/package/busybox/busybox.config. (They are not enabled inbusybox-initramfs.config.) There is nomtd-utilspackage in the tree. - No in-tree board currently boots
root=ubi— the only occurrence of that string is sysupgrade's own comment. So this is enabling work for NAND/ubifs devices rather than a fix for a broken flow anyone is hitting today, which is worth weighing against the risk of touching the flash path again. - NAND is presently approximated:
download_firmwarewarns "the updater uses the NOR package for updating NAND" and proceeds.
Testing note
The offline suite (.github/scripts/test_sysupgrade.sh, 82 checks) cannot exercise a real pivot or real mounts — it runs unprivileged, and its pivot_root stub fails by default so that every existing case exercises the in-place fallback. Anything added here will need the same treatment: source invariants plus a real board. A ubifs change in particular cannot be validated on the NOR cameras used for #2252.
Activity
widgetii commentedon Oct 4, 2026
Done. sysupgrade upgrades UBIFS NAND cameras now, and the NAND layout itself changed so nothing has a fixed size.
Layout. The u-boot-xmedia SoCs (GK7205V500/V510/V530, Hi3516EV200/EV300/DV200, Hi3518EV300) use one UBI device from 1 MiB:
rootfsvolume with the kernel inside it as/boot/fitImage, hashed and checked by U-Boot before it boots;rootfs_datafor the settings.No flash is set aside for a kernel, and both volumes are sized by their images.
Upgrade path. This answers the three gaps listed above:
The old root is released. busybox init's
::restart:hands PID 1 into the RAM root, the old root is detached (umount -l), and every volume is closed before anything is written.There is a UBI write path. Running as PID 1, sysupgrade:
rootfs_data;rootfsto the image (ubirsvol);ubiupdatevol);rootfs_dataon the rest;If the settings can't be copied, or don't fit beside the new image, the run stops with nothing written.
The layout is detected from
/proc/cmdlineand the UBI volumes.The
--webquestion was settled the way you'd expect: the WebUI log stops when PID 1 moves into RAM, and the MTD path is unchanged.Retired layouts. These are refused before anything is downloaded or written, with a link to the reinstall instructions:
kernelpartition);kernelvolume;Before this, a split-layout camera got a NOR squashfs written through gluebi over its mounted UBIFS.
Verified on a hi3516ev300 (W25N01GV NAND):
nand erase.part ubi,nand write.trimffs) and withdefib install --nand;/boot/fitImagewithcrc32+ sha1+ OK;sysupgrade -rresizedrootfs(155 → 138 LEBs), kept the settings, and came back.Landed in: