Sysupgrade would cut down the size of preserved files (partition size, emmc)

Hi all,

I'm running OpenWRT v21.02.5 on a UniElec U7623 machine, the image was compiled by me.
I know by adding entries in /etc/sysupgrade.conf, I could preserve that file that I don't want to overwrite during the upgrade or re-flash. And I have added a JPG which would be displayed on a OpenNDS Captive Portal.
However, I noticed that if the JPG is too large, probably if larger than 2MB, the image will lose pixels after an sysupgrade. Below is JPG after the sysupgrade.

It is interesting when I examined the property, seems like the image still holds the same amount pixels (3113x3113) and the clarity, so it must be written as null or something in the file itself, neither cropped nor compressed. Here are the reported sizes.

root@openwrt:~# ls -lth /etc/opennds/htdocs/images/banner.jpg 
-rw-r--r--    1 root     root        2.1M Mar 23 21:14 /etc/opennds/htdocs/images/banner.jpg
......after_upgrade......
root@openwrt:~# ls -lth /etc/opennds/htdocs/images/banner.jpg 
-rw-r--r--    1 root     root      891.0K Jan  1  1970 banner.jpg

This is really annoying, I wonder how could this happen, the onboard storage is plentiful as well.

root@openwrt:~# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root                11.0M     11.0M         0 100% /rom
tmpfs                   248.5M    140.0K    248.4M   0% /tmp
/dev/loop0              243.1M     88.7M    154.4M  36% /overlay
overlayfs:/overlay      243.1M     88.7M    154.4M  36% /
tmpfs                   512.0K         0    512.0K   0% /dev

I have also tried renaming a 10MB binary file to the banner.jpg and put it at the same place, it also reduced the size to 2MB after the sysupgrade...

Any ideas?

Thanks!

With some experiments, basically just re-flashing the same image with the same JPG, there are some of my observations.

  1. The JPG will always reduce to the same size, and it will not get further cut down when re-flash again.
  2. The original size of the JPG matters, different JPGs will be cut down to different size not a fixed size. A big JPG after cut down can be larger than the original small JPG before the cutd down.
  3. If the JPG is way too large (say 20MB), the JPG will be reverted to the OpenNDS package default one not the one I uploaded.

Is that image

  • part of the compiled firmware image, or
  • a file in overlay that should be copied in sysupgrade?

It sounds like the latter choice.
It would be better to include it in the image itself as a custom file.

If you manually create a backup file, how large is that? You have used 89 MB of overlay, so is the backup file 89 MB sized?

For most routers, the sysupgrade happens so that first the image is written to flash and then the preserved settings/files are written to flash at the image's end.

It could even be that there is a bad flash block that somehow comes affect things.

Have you tested with multiple picture files included? (Trying to move the file's location in archive)

1 Like

That interpretation is actually wrong. Everything is overwritten (for routers with normal sysupgrade and normal hand/nor flash).

The preserved contents are just copied via backup file.

2 Likes

The JPG image will be a file in the overlay

Here I want provide a customization feature so the Captive Portal login page could show different banner. Can't re-compile a new image every time I want to change my puppy photo to my cat photo. :grinning:

It is way less than that and is ~3MB

I have tested with 3 JPGs that are uploaded to the /root/, sizes are 5MB, 15MB and 20MB. I have added the path to them into /etc/sysupgrade.conf . After the reflash they were all gone :smiling_face_with_tear:.

sysupgrade.conf

root@openwrt:~# cat /etc/sysupgrade.conf 
## This file contains files and directories that should
## be preserved during an upgrade.

# /etc/example.conf
# /etc/openvpn/
/etc/opennds/htdocs/images/banner.jpg
/root/5mb.jpg
/root/15mb.jpg
/root/20mb.jpg

Output from ls at /root

root@openwrt:~# ls -lth
-rw-r--r--    1 root     root       20.4M Mar 24 18:11 20mb.jpg
-rw-r--r--    1 root     root       15.1M Mar 24 18:10 15mb.jpg
-rw-r--r--    1 root     root        5.0M Mar 24 18:10 5mb.jpg

Output from df

root@openwrt:~# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root                11.3M     11.3M         0 100% /rom
tmpfs                   248.5M    336.0K    248.2M   0% /tmp
/dev/loop0              242.8M    127.7M    115.0M  53% /overlay
overlayfs:/overlay      242.8M    127.7M    115.0M  53% /
tmpfs                   512.0K         0    512.0K   0% /dev

Backup file size

After the re-flash

root@openwrt:~# ls -lth
root@openwrt:~# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root                11.3M     11.3M         0 100% /rom
tmpfs                   248.5M    116.0K    248.4M   0% /tmp
/dev/loop0              242.8M     87.0M    155.7M  36% /overlay
overlayfs:/overlay      242.8M     87.0M    155.7M  36% /
tmpfs                   512.0K         0    512.0K   0% /dev
root@openwrt:~# cat /etc/sysupgrade.conf 
## This file contains files and directories that should
## be preserved during an upgrade.

# /etc/example.conf
# /etc/openvpn/
/etc/opennds/htdocs/images/banner.jpg
/root/5mb.jpg
/root/15mb.jpg
/root/20mb.jpg

Also tried running "sysupgrade -b", the JPGs in the backup archive is unaltered. Removing the JPGs in /root then "sysupgrade -r" will recover the JPGs to the original size.

Right, my mistake there, thanks!

So I have doing some more research and experiment. Now I think the reason is the limited size of the "recovery" partition being used for storing the backup archive during upgrade.

root@openwrt:~# lsblk
NAME         MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
loop0          7:0    0  242M  0 loop /overlay
mmcblk0      179:0    0  7.3G  0 disk 
├─mmcblk0p1  179:1    0    3M  0 part    <------ This one
└─mmcblk0p2  179:2    0  256M  0 part /rom
mmcblk0boot0 179:8    0    4M  1 disk 
mmcblk0boot1 179:16   0    4M  1 disk 

And in the /openwrt/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh

//Line 98
recoverydev=mmcblk0p1
			mkdir -p /tmp/recovery
			mount -o rw,noatime /dev/$recoverydev /tmp/recovery
			[ -f "/tmp/recovery/mac_addr" ] && \
				mv -f /tmp/recovery/mac_addr /tmp/
			umount /tmp/recovery
//...
//Line 166
		# platform_do_upgrade() will have set $recoverydev
		if [ -n "$recoverydev" ]; then
			mkdir -p /tmp/recovery
			mount -o rw,noatime "/dev/$recoverydev" -t vfat /tmp/recovery
			cp -af "$UPGRADE_BACKUP" "/tmp/recovery/$BACKUP_FILE"
			sync
			umount /tmp/recovery
		fi
		;;
//...

And I notice the eMMC is actually not being fully utilized, I wonder how could I resize the partition, especially how could I do it at the compile time. Or, could I even do that?

I found that in the dts file, there is a line

bootargs = "root=/dev/mmcblk0p2 rootfstype=squashfs,f2fs console=ttyS0,115200 blkdevparts=mmcblk0:3M@6M(recovery),256M@9M(root)";

This "3M@6M" seems quite related, but I could not understand the syntax for this line, could anyone share some insights? Could I just modify it so the "recovery" partition would just expand without bricking my router?
OK so obviously this is only the boot up commandline argument.

Great find. So ok, your router is not a normal one with a dumb flash chip (like majority of routers). That causes the process to deviate from default, as there are real partitions.

There is discussion about partition resizing, mostly related to x86 or RPi devices. You might search forum for that, and additionally you might edit/clarify the title of this thread to get attention from people with emmc / memory card partition knowledge.

2 Likes

Actually I'm using the Legacy image, looks like the partition is hard-coded and contains vendor specific information(MAC, SN...). I flashed the non-Legacy image and it increase the "recovery" partition, but erased the vendor info which seems to break the WiFi driver, since it cannot set the interface's MAC anymore...

Seems like I cannot edit the title anymore, not even the post body.

To update, I have modified the bootarg in the dtsi file, and the gen_mt7623_emmc_img.sh under the /target/linux/mediatek/image. Basically allowing the "recovery" partition to have 40M instead of 3M.

Now the router could boot up with more space in the mmcblk0p1 partition without erasing vendor information, but the problem still exists. I would try to investigate more.