Developing new device target: retaining rootfs_data across upgrade

I feel like this is a topic that has some answers buried somewhere in the knowledge base, but I haven't been able to figure it out. I'll lay out my details:

I'm developing a port for a new IPQ4019-based device, which has a 4GB eMMC. I think I've got a handle on all the other device-specific problems (e.g., DTS, laying out a partition table that the bootloader likes, etc.), but I'm having trouble with what to do with the rootfs and rootfs_data split. Particularly, mount_root seems to like to place rootfs_data immediately after my squashfs root -- this works as long as the rootfs stays exactly the same size (modulo ~64K of padding?) but this causes problems if the rootfs changes significantly on upgrades, as this may overlap with rootfs_data, losing my data filesystem.

It seems like I'm really missing something, since this obviously works for other devices. It probably doesn't help that most ipq4019 platforms are built for NAND flash, so I have to cheat off other targets (e.g., x86) to utilize block device / GPT support.

I'll throw out a few possible solutions, but I can't really tell what's the "right" way to support this:

  1. Add an extra GPT partition for rootfs_data (instead of just stealing the tail of the rootfs partition)
  2. Teach sysupgrade to resize, move, or save/restore /overlay every time (including filesystem reformatting/shrinking?)
  3. Force some padding into the squashfs root, so it always retains a fixed size and some room to grow

There already seems to be some support for #2, but it's a little hard for me to follow, and some of this is necessarily implemented in the platform.sh sysupgrade hooks, which...well, I'd have to understand enough to write (or copy/paste/modify) my own :wink:

Tips are welcome! Documentation links welcome too. I've perused the existing docs (sysupgrade technical reference, sysupgrade user docs), but they mostly seem to assume a basically stable underlying layout.

not a solution but... i had a similar device and the oem firmware used ext4 eMMC...

took the easy way out... and used a "spare" partition for rootfs/data... and used untar vs dd to add the files there as the partition has other OEM files there...

it was hard to get my head around the OEM partitioning... + integrating openwrt installation using ext4 on eMMC (threw squashfs out the window)... alas... these methods make official PR's troublesome...

these are some notes from the original post / topic that was called "eMMC sysupgrade help" sadly... no clear response materialised.

regarding your question... option4(left-field): use loopback file for rootfs_data.

Thanks for the thoughts -- and the sympathy; it's nice to know I'm not the only one who gets a bit lost here!

But you still have to teach the main rootfs to recognize and mount this extra partition, right? I was hoping to use the traditional read-only/squashfs support, where only my own modifications (extra packages/configuration) go on the data partition.

Any pointers on how that works? You still need a filesystem to put it on. So I guess that's still with a read/write rootfs like ext4?

here is one code snippet from zyxel.sh not necissarily your use case (3?) but a reference none the less;

snippet
	echo "flashing rootfs to ${rootfs}"
	tar xf $tar_file ${board_dir}/root -O >"${rootfs}"

	# a padded rootfs is needed for overlay fs creation
	local offset=$(tar xf $tar_file ${board_dir}/root -O | wc -c)
	[ $offset -lt 65536 ] && {
		echo Wrong size for rootfs: $offset
		sleep 10
		reboot -f
	}

	# Mount loop for rootfs_data
	local loopdev="$(losetup -f)"
	losetup -o $offset $loopdev $rootfs || {
		echo "Failed to mount looped rootfs_data."
		sleep 10
		reboot -f
	}

	echo "Format new rootfs_data at position ${offset}."
	mkfs.ext4 -F -L rootfs_data $loopdev
	mkdir /tmp/new_root
	mount -t ext4 $loopdev /tmp/new_root && {
		echo "Saving config to rootfs_data at position ${offset}."
		cp -v "$UPGRADE_BACKUP" "/tmp/new_root/$BACKUP_FILE"
		umount /tmp/new_root
	}
commit 783875f18b073b0fbe3281293e51781fa372ce7f
    package/basefiles: add mkfs.ext4 and losetup binaries to ramfs list
    mkfs.ext4 und losetup are needed for sysupgrade support on mmc devices
    with automatic rootfs split (loopback device usage).

commit 1465bebd74537fc38d1b4457a331331d58ca6d43
    ipq806x/nbg6817: add sysupgrade support
    Add new way of flashing to mmc devices based on rootfs split with loop devices