Skip to content

fix(os): restore NVMe /data persistence (ext magic instead of BusyBox blkid) - #44

Open
keskad wants to merge 4 commits into
mainfrom
fix/restore-nvme-persistence
Open

fix(os): restore NVMe /data persistence (ext magic instead of BusyBox blkid)#44
keskad wants to merge 4 commits into
mainfrom
fix/restore-nvme-persistence

Conversation

@keskad

@keskad keskad commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Restores fb11934 (fix/nvme-data-persistence) onto current main. That commit never landed (reset off main on 2026-08-24, recovered onto the branch, no PR).

BusyBox blkid in the image ignores -o value -s TYPE, so both early-boot.sh and prepare-nvme never saw ext4 and skipped mounting NVMe:

nvme: /dev/nvme0n1p1 blkid TYPE="" … (want ext4) — skipping mount

What this brings back

  • Detect ext superblock magic 0xEF53 at offset 0x438 in Rust (is_ext_family) and in early-boot.sh (dd/od), instead of blkid -o/-s.
  • Select /data by device path (marked NVMe first, then /dev/mmcblk0p3); relabel SD bigfred-sdboot so BusyBox findfs cannot pick the wrong volume.
  • Atomic copy + verified marker; status / adopt / reinit on prepare-nvme; UI GET /api/v1/storage banner when NVMe is present but /data is still on SD.
  • /data/bin first on PATH; SSH host keys under /data/etc/dropbear.
  • scripts/check-os.sh fails the build if blkid -o / blkid -s reappear.

MICRONET_REF stays on main (the two follow-up pin/unpin commits on the source branch cancel out).

Local scripts/check-os.sh: OK.

keskad and others added 4 commits August 24, 2026 14:57
/data never stayed on the NVMe: three independent bugs kept it on the SD
card, so flashing an image wiped the SQLite database along with it.

The image ships BusyBox blkid, which ignores -o value -s TYPE, so the type
check never returned ext4 and both early-boot and prepare-nvme skipped the
disk. Detect the ext superblock magic at offset 0x438 instead, in both.

SD p3 and NVMe p1 both carried LABEL=bigfred-data, and BusyBox findfs scans
/dev with an unsorted readdir(), so /data could land on either between boots.
Select by device path only (marked NVMe partition first, then /dev/mmcblk0p3)
and relabel the SD partition bigfred-sdboot so the collision cannot return.

The migration marker was written after a non-atomic `cp -a` whose status was
discarded, so a partial copy left a populated tree with no marker, which
later boots read as "not empty, skip forever". Copy excluding ephemeral
run/ and logs/, verify the result, then write the marker and sync. A
non-empty ext4 volume without a marker is now reported as unmigrated-dirty
for `adopt` or `reinit --yes` rather than silently ignored, and formatting
only happens on a just-created partition or a confirmed-empty ext volume.

Binary overrides lived in three layouts across seven mechanisms (two
wrappers, resolve_bin, and four init scripts with their own /data/opt
paths). Replace all of them with /data/bin first on PATH: init scripts exec
bare names, the package installs real binaries to /usr/bin, and the UI
Update tab installs to /data/bin. A changed image commit resets /data/bin so
stale overrides do not outlive the image they were built against.

SSH host keys move to /data/etc/dropbear so the fingerprint survives reboot
and OS flash once /data itself persists. They are generated by the dropbear
service rather than early-boot, because dropbearkey reads /dev/urandom
without blocking and the CRNG may still be uninitialized that early.

prepare-nvme grows status/adopt/reinit for operators, and reinit refuses to
wipe a disk that still backs any mount: early-boot binds /etc/shadow,
/root/.ssh and /etc/dropbear off /data, and those keep the filesystem live
after `umount /data`. The UI exposes GET /api/v1/storage and shows a banner
when an NVMe is present but /data is still on the SD.

Co-authored-by: Cursor <cursoragent@cursor.com>
Bump MICRONET_REF after micronet CI published the artifact with null=auto
Ethernet selection (first physical iface with carrier after PHY poll).

Co-authored-by: Cursor <cursoragent@cursor.com>
Carrier-based iface selection is on micronet main; no sha pin needed.

Co-authored-by: Cursor <cursoragent@cursor.com>
Restore the NVMe /data persistence fix (fb11934): detect ext superblock
magic instead of BusyBox blkid -o/-s TYPE, which never returned ext4 and
skipped mounting /dev/nvme0n1p1.
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