Expanding OpenWrt squashfs image (SDcard)

Hello,
The thread Expanding OpenWrt squashfs image? (SDcard) by @hadmut1 was closed, so I started this similar topic for expanding the ext4 overlayFS for a Raspberry Pi.

What works for me is the following outline:

  1. Transfer OpenWRT to SD-card, boot from that SD-card, log into the RaspberryPI
  2. Install additional packages
  3. Delete the second partition and create a new one with the same start sector and the suggested full length of the SD-card
  4. reboot and log in again
  5. resize the ext4 partition while it is mounted
  6. reboot again just to check if everything went well

A bit more in detail:

  1. At the PC:
#unzip the Image
gzip -d openwrt-21.02.0-bcm27xx-bcm2708-rpi-squashfs-factory.img.gz
# insert SD-card and check the name, alternatively check dmesg
lsblk
# copy the Image 1:1 to the SD-card
sudo dd if=openwrt-21.02.0-bcm27xx-bcm2708-rpi-squashfs-factory.img of=/dev/mmcblk0 bs=1M conv=fsync
  1. SSH into the Raspberry Pi:
opkg install kmod-usb-storage kmod-usb-ohci kmod-usb-uhci e2fsprogs fdisk resize2fs
  1. fdisk /dev/mmcblk0 (also see the less finicky way by @SemperEnim below):
    To make it clear what I entered, here the complete session of fdisk. Please note how the first sector remains unaltered:
Welcome to fdisk (util-linux 2.36.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): p
Disk /dev/mmcblk0: 14.99 GiB, 16096690176 bytes, 31438848 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x5452574f

Device         Boot  Start    End Sectors  Size Id Type
/dev/mmcblk0p1 *      8192 139263  131072   64M  c W95 FAT32 (LBA)
/dev/mmcblk0p2      147456 360447  212992  104M 83 Linux

Command (m for help): d
Partition number (1,2, default 2): 2

Partition 2 has been deleted.

Command (m for help): n
Partition type
   p   primary (1 primary, 0 extended, 3 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (2-4, default 2): 2
First sector (2048-31438847, default 2048): 147456
Last sector, +/-sectors or +/-size{K,M,G,T,P} (147456-31438847, default 31438847): 

Created a new partition 2 of type 'Linux' and of size 14.9 GiB.
Partition #2 contains a squashfs signature.

Do you want to remove the signature? [Y]es/[N]o: n

Command (m for help): p

Disk /dev/mmcblk0: 14.99 GiB, 16096690176 bytes, 31438848 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x5452574f

Device         Boot  Start      End  Sectors  Size Id Type
/dev/mmcblk0p1 *      8192   139263   131072   64M  c W95 FAT32 (LBA)
/dev/mmcblk0p2      147456 31438847 31291392 14.9G 83 Linux

Command (m for help): w
The partition table has been altered.
Syncing disks.
  1. reboot and log in again
  2. The device usage and sizes are now as follows (my SD-card is 16 GB in size). The size needs still needs to be adjusted:
df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root                 4.3M      4.3M         0 100% /rom
tmpfs                   217.9M     52.0K    217.9M   0% /tmp
/dev/loop0               92.7M      2.6M     83.1M   3% /overlay
overlayfs:/overlay       92.7M      2.6M     83.1M   3% /
/dev/mmcblk0p1           63.9M     17.3M     46.6M  27% /boot
tmpfs                   512.0K         0    512.0K   0% /dev

Actually this was easier than expected, simply use resize2fs:

resize2fs /dev/loop0

resize2fs 1.45.6 (20-Mar-2020)
Filesystem at /dev/loop0 is mounted on /overlay; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 120
The filesystem on /dev/loop0 is now 15641408 (1k) blocks long.

And now df -h returns the adjusted size:

df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root                 4.3M      4.3M         0 100% /rom
tmpfs                   217.9M     56.0K    217.9M   0% /tmp
/dev/loop0               14.5G      3.1M     13.9G   0% /overlay
overlayfs:/overlay       14.5G      3.1M     13.9G   0% /
/dev/mmcblk0p1           63.9M     17.3M     46.6M  27% /boot
tmpfs                   512.0K         0    512.0K   0% /dev
  1. Just reboot and check if everything went well. Done :smiley:

Edit #1: @SemperEnim pointed out below, that there is a less finicky alternative to using fdisk for step 3 ff:

1 Like

Alternatively instruct image builder how large the partitions are made.

The BASH-script below is also generating SquashFS & F2FS images, which should make the RPi less susceptible to power-loss induced filesystem corruption. Please consider using those images if your RPi does not have a uninterruptible-power-supply:

#!/bin/bash

#Documentation: https://openwrt.org/docs/guide-user/additional-software/imagebuilder

OUTPUT="$(pwd)/images"
BUILDER="https://downloads.openwrt.org/releases/21.02.0/targets/bcm27xx/bcm2708/openwrt-imagebuilder-21.02.0-bcm27xx-bcm2708.Linux-x86_64.tar.xz"
KERNEL_PARTSIZE=128 #Kernel-Partitionsize in MB
ROOTFS_PARTSIZE=4096 #Rootfs-Partitionsize in MB

# download image builder
if [ ! -f "${BUILDER##*/}" ]; then
	wget "$BUILDER"
	tar xJvf "${BUILDER##*/}"
fi

mkdir "$OUTPUT"
cd openwrt-*/

# list all targets for this image builder, consider 'make help' as well
# make info

# clean previous images
make clean

# Packages are added if no prefix is given, '-packaganame' does not integrate a package
sed -i "s/CONFIG_TARGET_KERNEL_PARTSIZE=.*/CONFIG_TARGET_KERNEL_PARTSIZE=$KERNEL_PARTSIZE/g" .config
sed -i "s/CONFIG_TARGET_ROOTFS_PARTSIZE=.*/CONFIG_TARGET_ROOTFS_PARTSIZE=$ROOTFS_PARTSIZE/g" .config

make image  PROFILE="rpi" \
           PACKAGES="kmod-rt2800-usb rt2800-usb-firmware kmod-cfg80211 kmod-lib80211 kmod-mac80211 kmod-rtl8192cu \
                     luci-base luci-ssl luci-mod-admin-full luci-theme-bootstrap \
                     kmod-usb-storage kmod-usb-ohci kmod-usb-uhci e2fsprogs fdisk resize2fs \
                     htop debootstrap" \
            BIN_DIR="$OUTPUT"

Edit #1: Suggest using SquashFS/F2FS. This combination is less susceptible to power-loss and subsequent filesystem-corruption.

I might have simplified the process a bit.

I find using fdisk is a little finicky, i got it to work following your instructions once but i failed multiple times after i deleted the partition and rebooted, it'd go into a boot loop.

However, i find not deleting the partition that comes with it, and expanding it using cfdisk works easier and is simplier. my install step looked more like this

opkg update && opkg install cfdisk resize2f

cfdisk /dev/mmcblk0

resize the bottom-most partition (it typically goes to max size automatically for you)

reboot and just run resize2fs

resize2fs /dev/loop0

Feel free to edit your instructions if you like.

EDIT: small edit needed following my own instructions and it didn't work.

1 Like

Thank you, I will give it a try myself if I need to reinstall or upgrade that RPi. I edited the post above so others, looking for help might see it immediately.

Take care that crashes and "brutal" power-off may broke your system !
I have this issue for long times and get it work in another way...

I advice that a third partition for overlay may be a better way...
I get some success to automate and also get auto-upgrade : Request for Best Practice for eMMC devices - #16 by erdoukki

This method still need some tweaks and also a few more tests, but I think it can be generally proposed and will help OpenWrt devices management to be more efficient and simpler !

1 Like

Thanks for the hint. I think the second method I posted, using image builder and squashfs/f2fs with large partitions is a quite power-loss-robust-way. What's your opinion on that one?

The rootfs will be live and any crash will broke it...
Next boot will not get it autorepaired and will give you in a unbootable state !
I have this issue too often on RPi.
You must then repair the uSD from another computer !

The good way is to have a ReadOnly rootfs, then block-mount and overlay will help to expand the storage.
In case of crash or power-fault, the rootfs will work and the overlay will be checked and auto-repaired...
The worst will only be an auto-reboot !

The two methods can be "mixed".
An image customized with image builder, which integrate block-mount and a f2fs overlay as a third partition (which can be resized at first boot) will be a great idea !

1 Like

F2FS is an overlay to the SquashFS. For EXT4 based images you are certainly right and likely that's vulnerable to powerloss-triggered-corruptions.

My understanding is, in case the F2FS-Overlay is damaged it will be checked (and fixed) at startup. Even if that fails, I expected the startup scripts to drop me to failsafe or at least run with just the SquashFS based read-only system.

I am not keen on intentionally corrupting the F2FS just to test it now, but perhaps that would be the way to clarify the behavior / confirm that assumption.

1 Like

You're right...
I do not seen the F2FS overlay from the given link.
But I agree with you it is the best way to handle crashes !

1 Like

I will make it more obvious and edit the post above.