X86_64 squashfs-combined & extra partitions

I am using an image builder to generate a firmware file which auto configures itself on the first boot. I would like to keep using generic-squashfs-combined-efi.img.gz that provides me with a quick rollback to something that is guaranteed to work.
I have made the roofs to be 2GB and there is still a lot of unallocated space that I want to use, but I am not sure if the extra partition will be preserved. The wiki page reads:

If extra partitions are added, you cannot use -combined.img.gz images anymore, because writing this type of image will override the drive's partition table and delete any existing extra partition, and also revert boot and rootfs partitions back to default size.

But sysupgrade has a flag that seems to apply that the extra partition will be preserved by default (I used this flag when writing an image with increased rootfs):

-p do not attempt to restore the partition table after flash.

So if the flag is not used (default), the extra partition should be preserved, but that contradicts the wiki page. Which one is correct?

I use an extra partition with release images (not custom built). The sysupgrade process preserves the partition table and the data in the extra partition.

Of course if you have anything important there, keep a backup before upgrading.

It is much less effort, to put the OpenWRT image onto an USB Stick or SD Card and boot from that. And keep the hard drive untouched a separate partition, mounted as drive. Skipping to effort, to resize partitions.

A suitable Stick or SD card is less that 5€/$.

This way you can also more easily apply OpenWRT updates by simply using a second stick, switching as needed, without having to mess with repartitioning again and without risking data loss on remaining drive partitions.

It is an options, but there is no resizing required if a sys upgrade image is used. I just need to create a new partition once and mount it with fstab. The firmware itself includes a 2GB rootfs partition and that is only to store all the packages. I prefer the speed of the SSD, but if that proves unreliable, then I will have to go this route.

Hi.
That should also work with a custom build, as long as the partitions size remains the same?

That is really the crux of the matter. Yes, sysupgrade retains the partition table if the default partition sizes do not change. But even if we haven't seen it in a while, partition sizes may actually change between releases, so to some extent their size should be considered "variable".

Whenever this topic comes up I'm advocating adding additional partitions with plenty of buffer, i.e. don't start an additional data partition completely flush to the default OpenWrt partitions. Personally, I start them at a constant 1GB into the drive because, frankly, a "wasted" 900 MB on a hard disk or even a small-time SSD or MMC do not matter much. This way, even if the default partition sizes change and sysupgrade decides to wipe the partition table layout and write the new partitions to the disk wholesale, it would not overwrite additional partitions, which can then simply be restored by manually re-entering their partition data in fdisk/gdisk.

1 Like

That is fair, but this risk is manageable. Image builder allows me to change the defaults for kernel & rootfs partitions, so I have doubled the kernel partition size (16 --> 32) and increased the rootfs partition from 104MB to 2GB to cover for all the packages I want to add over time. By doing so I have taken over the partition sizes and any changes in the default will be overwritten by me, unless the new values are bigger than mine which is unlikely.
Then I am planning to create a partition for the rest of the disk and mount it from fstab. I have so far understood that the partitions will remain intact while using the squashfs image, that allows for a quick rollback.

CONFIG_TARGET_KERNEL_PARTSIZE=32
CONFIG_TARGET_ROOTFS_PARTSIZE=2048
1 Like

Interesting idea.
If I understood correctly ...

  • the first GB is used for OpenWrt partitions, whatever their lenghts are (actually 120 MB).
  • even if the partitions increase (slightly) in future, they will still fit in this first GB.
  • extra partition starts after the first GB, leaving some unused space before.
  • sysupgrade will not modify the partition table and the extra partition.

Now what about fstab ?
Is it kept while sysupgrading ("keep data" checked) or should the extra partition being readded manually ?
I must confess that I have a very poor experience of this in Linux.

My idea is to host a web server on the router, to acces data remotely. These data will be stored on an extra partittion. They are backuped, so they are expandable. But idealy I will gain time if I don't need to reinstall them on the extra partition after any sysupgrading.

I can now confirm that extra partition does survive when upgrading using squashfs-combined-efi via UI. Here is the final partition layout:

Device        Start       End   Sectors   Size Type
/dev/sda1       512     66047     65536    32M Linux filesystem
/dev/sda2     66048   4260351   4194304     2G Linux filesystem
/dev/sda3   4261888 976773134 972511247 463.7G Linux filesystem
/dev/sda128      34       511       478   239K BIOS boot

Partition 128 does not start on physical sector boundary.
Partition table entries are not in disk order.

I never keep config: my image includes a script that configures everything on the first boot, but it will work this way as well.

Here is what I did:

  1. Build firmware using Image Builder (not from source). I am using squashfs-combined-efi.img.gz. I set kernel/rootfs partition sizes to 32/2048MB in .config before running make image
  2. Write squashfs-combined-efi.img to SSD while booted into Ubuntu (from USB)
  3. Now I can either use gparted from Ubuntu to create the additional partition or boot into OpenWrt and create it from there with fdisk. blkid will tell me the partition UUID, that I will add into my setup script to configure a mount in fstab
  4. Now I do have to boot into OpenWrt
  5. Spin up a new firmware with correct UUID
  6. Use squashfs image to upgrade via UI without preserving config. I actually disable this flag to avoid mistakes sed -i 's/ALLOW_BACKUP=1/ALLOW_BACKUP=0/' /usr/libexec/validate_firmware_image
  7. All done. All subsequent upgrades will preserve the extra partition and the overall disk layout.

I am pretty happy with this setup after a few days.

Yes.

[this space intentionally left blank]

Ok, thank you everyone for all these infos. Sounds promising. I'll make some tests in a few days.

I'm in trouble to understand steps 5 and 6.

5 --> Image Builder
6 --> I run that command from /etc/rc.local (that I packaged into the image myself) to disable the "Keep Settings" prompt in LuCI.

And maybe this: https://openwrt.org/docs/guide-developer/uci-defaults

I am using this to add my custom scripts that include the UUID of the extra partition to mount from fstab.

Using the FILES option in make ?
So you directly insert into the image a file/script that mount the partition into fstab using the correct UUID ?
Ok, it's tricky.https://openwrt.org/docs/guide-developer/uci-defaults

Yes, FILES=
Not exactly. I add a script under /etc/uci-defaults/ that gets executed on the first boot and executes uci commands to configure /etc/config/fstab. Something like uci set fstab.mnt_data.uuid=blah. There are way more steps, but that is the idea.

You can configure everything via LuCI and keep the config. That will also work.

Ok I got the idea. I'm a little rusty about all this.
Thank you for your patience.

That was exactly the point: combine the benefits of squashfs and also have an extra partition.

squashfs nor ext4 will provide this on their own. You need to spin up your own firmware or use luci-app-attendedsysupgrade

It is not just two images, but two separate steps. The first image is used to create OpenWrt partitions and then create a new partition for the rest of the disk (I used fdisk for that). Then blkid will tell me the partition UUID that I add to my setup script that is a part of my firmware. My script in the second image will instruct OpenWrt to mount it as /opt in /opt/config/fstab (Mount Points in LuCI).

Affirmative.

Correct. A new partition is created for the unused space. squashfs cannot be extended, only ext4.

Negative. The packages are a part of the firmware I build using Image Builder: see PACKAGES=.

This is not how it works. PROFILE=generic and I do not place downloaded squashfs into it. All packages are already in it via PACKAGES=.

What flags? The only thing I do is to increase the partition sizes:

sed -i 's/^CONFIG_TARGET_KERNEL_PARTSIZE=.*$/CONFIG_TARGET_KERNEL_PARTSIZE=32/g' .config
sed -i 's/^CONFIG_TARGET_ROOTFS_PARTSIZE=.*$/CONFIG_TARGET_ROOTFS_PARTSIZE=2048/g' .config

I would advice you to experiment with the Image Builder first. Then you may want to look into /etc/uci-defaults for auto-configuration if you want. Adding a partition will be easier after.

Image Builder
x86/64 Build

Here is a basic recipe:

wget https://downloads.openwrt.org/releases/22.03-SNAPSHOT/targets/x86/64/openwrt-imagebuilder-22.03-SNAPSHOT-x86-64.Linux-x86_64.tar.xz
tar Jxf openwrt-imagebuilder-22.03-SNAPSHOT-x86-64.Linux-x86_64.tar.xz
cd openwrt-imagebuilder-22.03-SNAPSHOT-x86-64.Linux-x86_64
sed -i 's/^CONFIG_TARGET_KERNEL_PARTSIZE=.*$/CONFIG_TARGET_KERNEL_PARTSIZE=32/g' .config
sed -i 's/^CONFIG_TARGET_ROOTFS_PARTSIZE=.*$/CONFIG_TARGET_ROOTFS_PARTSIZE=2048/g' .config
make image PROFILE=generic PACKAGES="unzip tar htop fdisk"

The squashfs & ext4 images will be under /firmware.

Once you make this work, you will be ready to proceed to the next step.

1 Like