This note is intended for users who have some experience in general computing and system administration but are relatively new to OpenWrt. It is loosely based on the relevant sections of the official OpenWrt on x86 Hardware page:
https://openwrt.org/docs/guide-user/installation/openwrt_x86
This note is current as of OpenWrt version 22.03.2.
The origins of OpenWrt lie far outside of the x86 ecosystem. As a result, it is distributed in a way that is not common in the x86 ecosystem. There is no installation media and no installer; rather, one must copy the installation image to the target system's hard drive or SSD. Because of this, a new installation of OpenWrt 22.x.x. typically has a boot drive with approximately 120 MB of total space, regardless of the actual capacity of the drive. There are two ways to reclaim the remaining capacity. One is to resize the root partition of the OpenWrt installation, and this is what this note is about. The other is to create one or more additional partitions, but we will not cover it here (it's a general Linux topic for which numerous tutorials are available).
There are four mainstream images one can use to implement an OpenWrt system on x86 hardware. (There are also other images used in special situations, which, for the purposes of this note, we will ignore.) They form a sort of 2x2 matrix:
In all of these images, there is also a boot partition, always with ext2 file system, but for our purposes here, it is not very important. We should know it exists and contains a small set of files needed to boot the system, but we're not going to do much with it in this note.
Both the nature of the firmware (BIOS vs. UEFI) and the type of file system on the root partition (ext4 vs. SquashFS) have implications for partition resizing. So the first step in resizing your root partition is to know what kind of system you have or, said another way, which image was used to install the system.
Resizing the root partition on a BIOS system is simpler. Only two steps are required:
On a UEFI system, there is an additional step required. UEFI, unlike BIOS, keeps track of partition identifiers. At boot, UEFI will allow the system to load only from a partition it recognizes. When we resize the root partition, its ID will change, so we'll have to communicate those changes to the UEFI. This is done by editing the grub
configuration file located at /boot/grub/grub.cfg. In order to know what changes to make to this file, it helps to see how partition configuration has changed. In other words, it is a good idea to have a record of both partition configurations, old and new. So in case of a UEFI system, we end up with a four-step process:
A note on safety
Technically, both resizing operations (resizing a partition and resizing a file system), if done on "live" drives, carry a risk of file system corruption. So in a perfect world, we should be doing this with the relevant drive unmounted (this can be achieved by booting the device from a USB stick). In practice, however, this works in an overwhelming majority of cases, especially when the device is essentially idle.
With this in mind, let's get some supplies.
You will need a few utilities, which you probably don't have installed. So let's get them:
opkg update && opkg install lsblk fdisk losetup resize2fs
These should take us through the process.
If you have a BIOS system, skip this section and go straight to Resize the Root Partition. On a UEFI system, run:
lsblk -o PATH,SIZE,PARTUUID
This wlll tell you the current partition layout, including each partition's unique identifier. Save this for future reference. If you're working over SSH, I would suggest saving it on the administrator's computer. Copy it from the terminal and save it as a text file. If you have a monitor and keyboard connected to your device, save it into a text file on the device. For example:
lsblk -o PATH,SIZE,PARTUUID > /root/lsblk_old.txt
Just in case, you may want to copy this file to a USB stick.
Next, you may want to take a look at the grub
configuration file:
cat /boot/grub/grub.cfg
The goal is to see where partitions' unique identifiers are used and, therefore, where you will need to replace them when the time comes. Take a look at this example:
root@OpenWrt:~# lsblk -o PATH,SIZE,PARTUUID
PATH SIZE PARTUUID
/dev/sda 120M
/dev/sda1 16M c959470f-01
/dev/sda2 104M c959470f-02
root@OpenWrt:~# cat /boot/grub/grub.cfg
serial --unit=0 --speed=38400 --word=8 --parity=no --stop=1 --rtscts=off
terminal_input console serial; terminal_output console serial
set default="0"
set timeout="5"
set root='(hd0,msdos1)'
menuentry "OpenWrt" {
linux /boot/vmlinuz root=PARTUUID=c959470f-02 rootwait console=tty0 console=ttyS0,38400n8 noinitrd
}
menuentry "OpenWrt (failsafe)" {
linux /boot/vmlinuz failsafe=true root=PARTUUID=c959470f-02 rootwait console=tty0 console=ttyS0,38400n8 noinitrd
}
root@OpenWrt:~#
It's easy to see that partition /dev/sda2 has a unique identifier c959470f-02, and that identifier is used in grub
configuration in two places to designate a root partition, first for the normal boot, then for the failsafe mode. So now you have a mind map of what you will be doing a little later.
This is done nearly identically in all cases by running an interactive fdisk
session. The listing below shows a mix of fdisk
output and manual inputs. To distinguish the manual inputs, we have enclosed them [[in double square brackets]]
; the [[]]
sequence indicates pressing Enter with no visible input. Obviously, when you enter commands or data, you won't need any square brackets; they are used only as markers. It's a bit confusing, but we can't come up with a better formatting scheme right now. So here goes:
root@OpenWrt:~# [[fdisk /dev/sda]]
Welcome to fdisk (util-linux 2.37.3).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
This disk is currently in use - repartitioning is probably a bad idea.
It's recommended to umount all file systems, and swapoff all swap
partitions on this disk.
Command (m for help): [[p]]
Disk /dev/sda: 59.63 GiB, 64023257088 bytes, 125045424 sectors
Disk model: ADATA_IM2S3134N-
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: 0xc120d9f5
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 512 33279 32768 16M 83 Linux
/dev/sda2 33792 246783 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 (33280-31277231, default 34816): [[33792]]
Last sector, +/-sectors or +/-size{K,M,G,T,P}
(33792-125045423, default 125045423): [[]]
Created a new partition 2 of type 'Linux' and of size 59.6 GiB.
Partition #2 contains a squashfs 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.
root@OpenWrt:~#
A few important notes:
33792
specified in response to the First sector
prompt came from the disk information table produced in response to the p
command.To verify that the partition has been resized, you can run fdisk -l
or start another interactive session (fdisk /dev/sda
) and issue a p
command to show the partition layout followed by a q
command to quit.
If you have a BIOS system, skip this section and go straight to Resize the Root File System. On a UEFI system, run:
lsblk -o PATH,SIZE,PARTUUID
Compare the output to its earlier version that you saved. You will see that the unique identifier for the /dev/sda2 partition has changed. Use your new identifier to replace the old one in grub
configuration. For example, if you use vi
, you can do:
vi /boot/grub/grub.cfg
From your earlier review of grub
configuration, you would know how many instances of partition ID require replacement. Make the changes, save the file, and exit the text editor.
This is the final step, and it is done differently depending on whether you have an ext4 file system or a SquashFS file system. You should take care to execute the commands given below one by one (meaning, don't paste all of them into the command line at once; allow one command to finish before entering the next one).
Watch the output of the resize2fs
command. Normally, you would see some indication of file system size change. If, on the other hand, resize2fs
indicated it had nothing to do, reboot your device and repeat this step in its entirety. Rebooting will ensure that the changes made during the previous steps are applied to the system.
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}
resize2fs -f ${LOOP}
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 -n -l | sed -n -e "\|\s.*\s${ROOT#/dev}\s.*$|{s///p;q}")"
resize2fs -f ${LOOP}
If all of the above worked, congratulations! You have successfully resized the root partition on your OpenWrt device. You may want to reboot your device to ensure that everything starts up correctly.
Early in this guide, we discussed the two options for reclaiming disk space, extending the root partition and creating additional partitions. Those are not mutually exclusive; it is entirely possible to use them together (extending the root partition part-way and setting up new partition or partitions in the still-free disk space). Read up on fdisk
and its use in partition setup; this will allow you to create all kinds of configurations.