Resizing partitions
Be sure to resize the image before resizing partitions when installing in a VM.
An example fdisk operation on a 8GB flash drive:
Welcome to fdisk (util-linux 2.32). 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/sda: 7.2 GiB, 7751073792 bytes, 15138816 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: 0xcbad8a62 Device Boot Start End Sectors Size Id Type /dev/sda1 * 512 33279 32768 16M 83 Linux /dev/sda2 33792 558079 524288 256M 83 Linux Command (m for help): d Partition number (1,2, default 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): Partition number (2-4, default 2): First sector (33280-15138815, default 34816): 33792 Last sector, +sectors or +size{K,M,G,T,P} (33792-15138815, default 15138815): Created a new partition 2 of type 'Linux' and of size 7.2 GiB. Partition #2 contains a ext4 signature. Do you want to remove the signature? [Y]es/[N]o: n Command (m for help): w The partition table has been altered. Syncing disks.
Automated method:
opkg update opkg install fdisk BOOT="$(sed -n -e "/\s\/boot\s.*$/{s///p;q}" /etc/mtab)" DISK="${BOOT%%[0-9]*}" PART="$((${BOOT##*[^0-9]}+1))"ROOT="${DISK}${PART}" OFFS="$(fdisk ${DISK} -l -o device,start | sed -n -e "\|^${ROOT}\s*|s///p")" echo -e "p\nd\n${PART}\nn\np\n${PART}\n${OFFS}\n\nn\np\nw" | fdisk ${DISK}
Be sure to update the GPT partition UUID in the GRUB configuration when using efi.img.gz:
opkg update opkg install lsblk BOOT="$(sed -n -e "/\s\/boot\s.*$/{s///p;q}" /etc/mtab)" DISK="${BOOT%%[0-9]*}" PART="$((${BOOT##*[^0-9]}+1))" ROOT="${DISK}${PART}" UUID="$(lsblk -n -o PARTUUID ${ROOT})" sed -i -r -e "s|(PARTUUID=)\S+|\1${UUID}|g" /boot/grub/grub.cfg
Resizing filesystem
Be sure to resize partitions before resizing filesystem. Note that online resizing should work for both F2FS and Ext4 on OpenWrt 19.07, although F2FS requires rebooting to apply changes.
Resizing F2FS overlay
Resize F2FS overlay for squashfs-combined.img.gz:
opkg update opkg install losetup f2fs-tools LOOP="$(losetup -n -O NAME | sort | sed -n -e "1p")" ROOT="$(losetup -n -O BACK-FILE ${LOOP} | sed -e "s|^|/dev|")" OFFS="$(losetup -n -O OFFSET ${LOOP})" LOOP="$(losetup -f)" losetup -o ${OFFS} ${LOOP} ${ROOT} fsck.f2fs -f ${LOOP} mount ${LOOP} /mntumount ${LOOP} resize.f2fs ${LOOP}reboot
Resizing Ext4 rootfs
Resize Ext4 rootfs for ext4-combined.img.gz:
opkg update opkg install losetup resize2fs BOOT="$(sed -n -e "/\s\/boot\s.*$/{s///p;q}" /etc/mtab)" DISK="${BOOT%%[0-9]*}" PART="$((${BOOT##*[^0-9]}+1))" ROOT="${DISK}${PART}" LOOP="$(losetup -f)" losetup ${LOOP} ${ROOT} fsck.ext4 -y ${LOOP} resize2fs ${LOOP} reboot
Adding extra partitions
When OpenWrt is installed on a x86 machine using generic-ext4-combined.img.gz, the drive's partition table is overwritten, which means that any existing partition is deleted. Any remaining space will be unallocated and the drive will have a normal MBR partition table.
Any partition management tool that supports MBR and ext4 can be used to create extra partitions on the drive, in example fdisk, GParted.
But attention must be taken for future upgrades. 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.
Upgrading
On most embedded devices, upgrading OpenWrt is much simpler than the first installation and consists of simply executing sysupgrade. On x86 machines, on the other hand, upgrading is more complex than the first installation.
One of the advantages of x86 is the easiness to backup and restore drives, using any normal backup tool that supports MBR and ext4. Always make a proper backup of the whole drive and test its restore before any upgrade procedure. It's also recommended to restore the backup on a virtual machine and execute the upgrade on it prior to upgrading the real router, to learn and experiment the procedures without risking the real thing.
On all procedures on this section, we must either connect the drive on a secondary PC running Linux, or boot the router with a Linux Live CD/USB.
If you had used a ext4-combined.img.gz type of image to install, there are 4 options for upgrading:
The 2 last options require more steps to execute, but have the advantage of leaving MBR partition intact, therefore keeping boot and rootfs partitions sizes (in case of having resized them) and any extra partitions. At this time they are the most recommended methods of upgrading. The only exception is when new OpenWrt image brings a newer version of GRUB2. Part of GRUB2 is stored close to MBR and outside of partitions area, so we need to write a full ext4-combined.img.gz to update it.
Extracting boot partition image
The boot partition contains part of GRUB2 software, Linux kernel and grub.cfg
with boot options. rootfs partition contains OpenWrt files, packages and configs.
At the moment, it's not built a separated image file with boot partition, as it's available for rootfs. To be able to upgrade boot partition without overriding the whole drive, we must extract it from ext4-combined.img.gz, this requires a spare empty drive or a virtual machine.
We will end up with the partition image openwrt-19.07.8-x86-64-generic-ext4-boot.img. Back to OpenWRT machine/drive, if the drive is on sdd and GRUB2 boot partition is on sdd1, we can write the updated image with dd if=openwrt-19.07.8-x86-64-generic-ext4-boot.img of=/dev/sdd1
. Note we're here writing on the partition sdd1, not on the drive sdd.
Upgrading rootfs partition
As said above, there are 2 options for upgrading rootfs partition, when we are using the ext4 file system and not squashfs: writing ext4-rootfs.img.gz image or uncompressing rootfs.tar.gz into existing partition.
Writing ext4-rootfs.img.gz will delete any file on the partition. When using dd
, it will preserve partition's actual size, it won't revert its size to image's.
For uncompressing rootfs.tar.gz, we must mount rootfs partition, delete all files from it, then uncompress updated files.
It may be tempting to not delete config files, but the risk isn't worth it, because some file may conflict and not be properly upgraded. It's safer to backup config files (as we should also backup whole drive before upgrading) and copy them back after upgrading. I suggest going further and having a Subversion repository on another computer where all config files are saved and their changes are tracked, and use rsync to sync between the repository working copy and production files on the router.
# mount rootfs partition, in this example it's on sdd2mkdir /mnt/rootfsmount -v /dev/sdd2 /mnt/rootfscd /mnt/rootfs # delete all files on the partitionrm -Rf * # copy rootfs.tar.gz here then uncompress ittar -xvzf openwrt-19.07.8-x86-64-generic-rootfs.tar.gz # wait for uncompress then delete the filerm openwrt-19.07.8-x86-64-generic-rootfs.tar.gz
Building your own image with larger partition size
Anyone can compile OpenWrt from source, but it's a complex procedure with many options which require some experience, specially for using it on a production router.
Different from compiling, we can build our own custom image using the Image Builder. This doesn't compile the whole software, instead it downloads required packages from the same repository used by OpenWrt to install them. Image Builder builds the same image files used for installing and upgrading OpenWrt.
Due to that it's much simpler than compiling and offers great advantages, like adding directly to the image all packages we need, removing those we don't need, and also adding to it our config files. Having packages on the image, we don't need to reinstall all of them after an upgrade. And having our config files directly on the image, we don't need to reconfigure everything or copy all files from backup, which is specially difficult when default network configs don't work with our router's interfaces or it doesn't start with correct IP address. In many cases, OpenWrt will be back fully working on first boot after upgrading.
Another advantage for building a custom image is when the default rootfs partition size is too small to store all packages and we need to resize it. Note that, when following above procedures of installing then resizing partition and upgrading by writing partition image or extracting rootfs.tar.gz, we don't need to build the image with the final size of the partition. Doing so would result in the too large image file and would require enough RAM to store the whole file during building. It's recommended to use on the image just enough size to store all packages plus a small amount of free space.
Follow the Image Builder tutorial to setup the building environment using the x86/64 target. Once the building environment is setup, we use the make image
command to build an image, which results on a set of files with the types of images described on this page. They are saved on bin/targets/x86/64
inside the building folder.
Because x86 hardware doesn't have profiles, we don't need to use the PROFILE
parameter. With PACKAGES
parameter we set all packages we want to add to or remove from default list. The command make info
lists default packages list. FILES
parameter is used to add custom config and script files to be added to the image, it points to a folder which represents root folder when OpenWrt is running.
For changing default partition sizes use parameters CONFIG_TARGET_KERNEL_PARTSIZE
and CONFIG_TARGET_ROOTFS_PARTSIZE
. We can either edit .config
file on building folder or pass them directly to make image
. Example CONFIG_TARGET_KERNEL_PARTSIZE=128 CONFIG_TARGET_ROOTFS_PARTSIZE=512
.