Adjusting Disk Space Usage for OpenWrt x86 Custom Image

Hello everyone,

I have been developing with the invaluable help from this community. I am currently using OpenWrt's ImageBuilder to create a custom image for the x86 architecture. The generated image, generic-ext4-combined-efi.img.gz, is installed on my nvme0n1, which has a capacity of 256GB.

However, the created image only utilizes 104MB of disk space. Here is the current disk layout:

NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda           8:0    1  14.3G  0 disk 
└─sda1        8:1    1  14.3G  0 part 
nvme0n1     259:0    0 232.9G  0 disk 
├─nvme0n1p1 259:1    0    16M  0 part /boot
│                                       /boot
├─nvme0n1p2 259:2    0   104M  0 part /
└─nvme0n1p128 259:3    0  1007K  0 part

I want to adjust the image to utilize the full capacity of the disk. In my search, I found that in the .config file of the ImageBuilder, I could modify the following properties:

  • CONFIG_TARGET_KERNEL_PARTSIZE=...
  • CONFIG_TARGET_ROOTFS_PARTSIZE=...

So, I tried modifying them to:

  • CONFIG_TARGET_KERNEL_PARTSIZE=512
  • CONFIG_TARGET_ROOTFS_PARTSIZE=237,568

However, when I attempt to create the image using the make command, an error occurs:

> 
> 8931868 bytes (8.9 MB, 8.5 MiB) copied, 0.0142419 s, 627 MB/s
> dd: memory exhausted by input buffer of size 249108103168 bytes (232 GiB)
> make[3]: *** [Makefile:158: /home/ow-ib/build_dir/target-x86_64_musl/linux-x86_64/tmp/openwrt-22.03.5-x86-64-generic-squashfs-rootfs.img.gz] Error 1
> make[2]: *** [Makefile:189: build_image] Error 2
> make[1]: *** [Makefile:127: _call_image] Error 2

What am I doing wrong here? How can I create a custom image that utilizes all 232GB of the available space? I would greatly appreciate any insights or advice from the community.

Thank you in advance for your help. :flushed:

The problem here is twofold.

On the one hand, the image actually needs to be created on the build host, so while building you would have to have ~233 GB free space at your disposal, yes that will be compressed down (and an effectively empty filesystem will compress nicely), but you still would have to provide that much (pre-compression) free space (plus some margin) for the image build process.

The other issue (actually two in one) doesn't bite you yet, but would once you'd actually try to flash it:

  • sysupgrade will have to write this raw image out, meaning it would spend quite a lot time on writing 233 GBs of zeroes to the SSD while upgrading, not very tempting (even on a SSD that takes a considerable amount of time).
  • all that still has to fit into RAM (of your target router), which I'd be rather vary of
    • here we'd also run into a snag with the retaining settings bit, if that becomes very large (relative to the system RAM) as well

Bumping the limits is reasonable, but keep it sensible and manageable, like ~32 MB for the kernel (hey, use 128 MB, if you like) and (which is the more important bit) perhaps around 500 MB for the rootfs. This both makes the images easily fit onto your buildhost and into RAM of the target, while also not taking too long to write out during the sysupgrade - while at the same time providing very comfortable margins to avoid partitioning changes down the road. Mount the rest of the disk as a data partition, which will survive sysupgrades quite fine (as long as you don't change TARGET_KERNEL_PARTSIZE && TARGET_ROOTFS_PARTSIZE between builds and keep them stable).

3 Likes

Thank you for your helpful response!! I will look for a better way as you advisedI don't know a lot about this field.I will explore further and find a more suitable approach as

Then there's https://openwrt.org/docs/guide-user/advanced/expand_root

2 Likes

Thank you for your answer. I have modified the script a bit to make it run after the installation.
When I used the script directly in uci-default, I got an error that the reboot would loop infinitely
When the error did not occur, the following error was left in the log:

[306.469286] EXT4-fs (nvme0n1p2): error count since last fsck: 3
[306.475353] EXT4-fs (nvme0n1p2): initial error at time 1700094482: ext4_find_dest_de:1996: inode 73: block 586
[306.485758] EXT4-fs (nvme0n1p2): last error at time 1700094482: ext4_readdir:243: inode 85: block 598

Since I don't know much about this field, I couldn't find the cause.

For now, I handled it like this.
I'm posting this because I think it might be helpful to someone, but actually, I'm not sure if this is the right method.

First, before installation, I formatted the disk in ext4 format.
(I installed Finnix on USBd.)

mkfs.ext4 /dev/nvme0n1p1

Then, I flashed the image created by ImageBuilder to my disk.

dd if=openwrt-generic-ext4-combined-efi.img bs=1M of=/dev/nvme0n1

When creating the image, I put the script to extend the root partition and file system in uci-default. At this time, I prevented the infinite loop by not processing it if it had already been done.

<70-rootpt-resize>

#!/bin/sh

# Path to the flag file
FLAG_FILE="/etc/part_resized"

# Function to check if the partition is already resized
is_resized() {
    [ -f "$FLAG_FILE" ]
}

# Function to resize the partition
resize_partition() {
    echo -e "ok\nfix" | parted -l ---pretend-input-tty
    parted -s /dev/nvme0n1 resizepart 2 100%
    echo "rootpt resizing..."
    touch "$FLAG_FILE"
    reboot
}

# Check if the partition has already been resized
if is_resized; then
    echo "Partition already resized, skipping..."
    exit 0
else
    resize_partition
    exit 1
fi

<80-rootfs-resize>

#!/bin/sh

FLAG_FILE="/etc/fs_resized"

is_resized() {
    [ -f "$FLAG_FILE" ]
}

resize_filesystem() {
    losetup /dev/loop0 /dev/nvme0n1p2 2> /dev/null
    resize2fs -f /dev/loop0
    echo "resize2fs resizing..."
    touch "$FLAG_FILE"
    reboot
}

if is_resized; then
    echo "File system already resized, skipping..."
    exit 0
else
    resize_filesystem
    exit 1
fi

After that, I confirmed that the disk capacity increased from 104MB to 2229.22GB.

I'm not sure if this method is wise.
I wanted to create a separate partition as you advised, but I was not successful because I am not good at using Linux.

Please take a look and let me know if there is anything missing.
I hope this article will be helpful to others as well.
thank you for the reply. :slightly_smiling_face:

1 Like

you don't have to do this.

if you're installing from scratch, you can run fdisk nvme0n1
delete the 2nd partition, and recreate it with the size you want.
then dd the openwrt-rootfs image to nvme0n1p2,
and run resize2fs nvme0n1p2 afterwards.

as a last step, located on nvme0n1p1, edit /boot/grub/grub.conf and change the root=... entry to root=/dev/nvme0n1p2
you can also do this once you booted openwrt, after making the same change in the grub boot menu, during start up.

but the script's safer, for future upgrades.

I am currently working on creating firmware that will be installed on 13 routers to be used on ships.
So you should be able to upgrade.
So, isn't it better to use a script as you advised?
I think I took on a project that was too big for my experience.
Thank you for your kind reply. :grinning:

then my counter question would be, do they need the extra space ?
this adds risk to the upgrade sequence.
especially if you're doing unattended/remote upgrades.

if not, leave the partition size as it is, create an additional partition, instead of extending the one containing rootfs, or follow @slh's advice.

1 Like

Since this router will be used on a ship, we will not be able to prepare immediately if an error occurs, so we increased the disk capacity to sufficiently back up the log files.

I haven't yet considered problems with remote upgrades.

Now, let's look at how to create an additional partition and store the log backup file in that partition.
However, in that case, I wonder if it is possible to check the capacity in Lucy.

I'm not familiar with Linux, so I think I'll have to study a lot to handle this method.
If you have anything more to say to me, please do so.
I want to create safe software.
Thank you for your interest and advice :pray:

I think that's a better idea.

AFAIK it won't show, without customizing the webUI code.
perhaps if you trick it by faking a share, where I believe it's displayed.

you could implement logrotate, to compress, and later auto delete the logs, after a certain amount of time.

1 Like

Thank you for answer. With your help, the project's problems are being solved little by little. ^^ Thank you.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.