Bug 15555

Summary: Some wic arguments cause IMAGE_ROOTFS_EXTRA_SPACE to be ignored
Product: [Build System, Metadata & Runtime] OE-Core Reporter: adam.johnston <adam.johnston>
Component: Scripts and ToolsAssignee: Trevor Woerner <twoerner>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: Medium CC: randy.macleod, ross.burton, twoerner
Version: unspecified   
Target Milestone: 5.2   
Hardware: x86   
OS: Multiple   
Whiteboard:
OS type for building Yocto: --- Type of Regression: ---
Verified: Documentation change: No (bug/feature does not impact docs)

Description adam.johnston@arm.com 2024-07-18 09:28:17 UTC
Some wic options (e.g. --exclude-path) seem to cause wic to re-pack the image.
When it does this, IMAGE_ROOTFS_EXTRA_SPACE seems to be ignored and any extra space which was allocated is lost.

Using qemuarm64-secureboot in meta-arm which has a wic file, building an image with the default setup and got a 130mb boot partition and 163mb root partition.  Added IMAGE_ROOTFS_EXTRA_SPACE=500000 (500mb) and rebuilt, and the root partition grew as expected.

Add "--exclude-path boot/" to the rootfs partition and the extra space disappears

I am assuming this is not the expected result (or if it is it is not well documented).

As a workaround, I'm adding this to our partition...

ROOTFS_EXTRA_ARGS += "--extra-space ${@${IMAGE_ROOTFS_EXTRA_SPACE}}K"

... but I think there is a bug here (or at least a quick to be documented)
Comment 1 Randy MacLeod 2024-07-18 14:47:57 UTC
This is not really a bug so Ross may just add a note in the documentation.
wic has to handle multiple partitions so it's not clear where the extra space should be.
Comment 2 Ross Burton 2024-07-18 14:54:07 UTC
After discussing this on the triage call there are two schools of thought:

1) IMAGE_ROOTFS_EXTRA_SPACE refers to the plain image as built by do_image, and not the wic output. Thus, this is expected albeit not-obvious and undocumented behaviour, and should be documented as such.

2) If wic needs to edit the partition then it should estimate the space in the filesystem before edits, and ensure that much space is available after the edits.
Comment 3 adam.johnston@arm.com 2024-07-18 15:23:33 UTC
For the moment I think we will have to carry the work-around.

I will take a look at wic and at least see if I can understand where the free space is being lost.

If I can find a sensible way of preserving it that is generic, doesn't rely on IMAGE_ROOTFS_EXTRA_SPACE, and doesn't break everything else, I will send a patch.
Comment 4 Trevor Woerner 2025-04-07 05:32:19 UTC
If the wks file contains a "--source rootfs" then lib/wic/plugins/source/rootfs.py will be invoked. If the rootfs needs to be tweaked or modified, the rootfs.py plugin will make a copy of the rootfs and work on the copy. In other words, if the "--source rootfs" line of the wks file also contains any of:

    --exclude-path
    --include-path
    --change-directory
    --use-label (i.e. modify etc/fstab)

then the rootfs will be copied first, then the copy modified.

If, for example, the unmodified IMAGE_ROOTFS is:
    .../tmp/work/qemuarm64_secureboot-oe-linux/core-image-base/1.0/rootfs
The copy would be made at:
    .../tmp/work/qemuarm64_secureboot-oe-linux/core-image-base/1.0/tmp-wic/rootfs${LINENO}

where ${LINENO} is the line number where this "--source rootfs" line appears in the wks file.

When it comes time to making an actual partition of a specific filesystem type, lib/wic/partition.py::prepare_rootfs() is called. It is in this function that wic figures out if any extra rootfs padding needs to be added. The bitbake variable used to specify the ultimate rootfs size is ROOTFS_SIZE, and since this variable is only valid for the rootfs and not any others, the code also verifies that the partition being checked is ${IMAGE_ROOTFS}:

    rsize_bb = get_bitbake_var('ROOTFS_SIZE')
    rdir = get_bitbake_var('IMAGE_ROOTFS')
    if rsize_bb and rdir == rootfs_dir:
        <use rsize_bb>
    else:
        <calculate the partition size using "du -ks $p">

Normally this works fine, but, as pointed out above, this check will fail when lib/wic/plugins/source/rootfs.py has made a copy of the filesystem and the copy's path does not match the path of ${IMAGE_ROOTFS}. In this case the code assumes that this is not the rootfs partition and therefore does not handle it using these two ROOTFS variables.
Comment 5 Trevor Woerner 2025-04-07 15:36:17 UTC
One solution is to modify lib/wic/partition.py::prepare_rootfs(). At the part where it is trying to determine whether or not the partition being created is a rootfs, keep the existing "rdir == rootfs_dir" clause to check for the normal, unmodified rootfs, but add an additional check to see if this is a wic-generated copy.

A second potential solution would be to not create a copy in lib/wic/plugins/source/rootfs.py and make modifications to the original rootfs.

I'm guessing there is probably a good reason why the plugin creates the copy, so I'll create a patch that implements the first solution.
Comment 6 Trevor Woerner 2025-04-07 15:42:06 UTC
steps to reproduce:

1. start with the following *wks file:
    bootloader --ptable gpt
    part /boot --ondisk=vda --align 64 --size=100M --active --source bootimg-partition --fstype=ext4 --label boot --sourceparams="loader=u-boot"
    part /     --ondisk=vda                                 --source rootfs            --fstype=ext4 --label root

2. add the following to conf/local.conf:
    IMAGE_ROOTFS_EXTRA_SPACE = "500000"

3. build an image, e.g.
    $ bitbake core-image-base

4. run it in qemu:
    $ runqemu slirp nographic serial

5. verify the root partition has extra space:
    root@qemuarm64-secureboot:~# df -h
    Filesystem                Size      Used Available Use% Mounted on
    /dev/root               721.5M     67.4M    600.6M  10% /
    devtmpfs                477.7M         0    477.7M   0% /dev
    tmpfs                    40.0K         0     40.0K   0% /mnt
    tmpfs                   489.3M     92.0K    489.2M   0% /run
    tmpfs                   489.3M     68.0K    489.2M   0% /var/volatile
    /dev/vda1               120.4M     19.9M     91.4M  18% /boot

6. modify the "/" line of the *wks file to be:
    part /     --ondisk=vda --exclude-path boot/            --source rootfs            --fstype=ext4 --label root

7. rebuild, re-run in qemu
8. verify the rootfs is not using the IMAGE_ROOTFS_EXTRA_SPACE variable:
    root@qemuarm64-secureboot:~# df -h
    Filesystem                Size      Used Available Use% Mounted on
    /dev/root                73.4M     41.9M     25.8M  62% /
    devtmpfs                477.7M         0    477.7M   0% /dev
    tmpfs                    40.0K         0     40.0K   0% /mnt
    tmpfs                   489.3M     92.0K    489.2M   0% /run
    tmpfs                   489.3M     68.0K    489.2M   0% /var/volatile
    /dev/vda1               120.4M     19.9M     91.4M  18% /boot
Comment 7 Trevor Woerner 2025-04-07 15:50:11 UTC
after this fix:
    root@qemuarm64-secureboot:~# df -h
    Filesystem                Size      Used Available Use% Mounted on
    /dev/root               721.5M     47.4M    620.6M   7% /
    devtmpfs                477.7M         0    477.7M   0% /dev
    tmpfs                    40.0K         0     40.0K   0% /mnt
    tmpfs                   489.3M     92.0K    489.2M   0% /run
    tmpfs                   489.3M     68.0K    489.2M   0% /var/volatile
    /dev/vda1               120.4M     19.9M     91.4M  18% /boot

Doing the math we see that when the *wks file does not have the "--exclude-path" option, the root partition is actually wasting about ~20MB of space. The /boot partition is ~20MB in size, and without the "--exclude-path boot/" option, the rootfs contains these files, and then mounts the /boot partition on top of them making them inaccessible and wasting space in the rootfs filesystem.

After the fix, with the "--exclude-path" option, we can see that the rootfs has an extra ~20MB available since it does not contain the contents of the /boot partition.
Comment 8 Trevor Woerner 2025-04-08 20:58:37 UTC
patch with oe-selftest sent:
https://lists.openembedded.org/g/openembedded-core/topic/patch_wic_do_not_ignore/112161628
Comment 11 Trevor Woerner 2025-04-16 14:54:30 UTC
v3 patch passes AB:
https://autobuilder.yoctoproject.org/valkyrie/#/builders/35/builds/1369/steps/15/logs/stdio

(search for wic.Wic.test_exclude_path_with_extra_space)
Comment 13 adam.johnston@arm.com 2025-04-22 16:57:55 UTC
Verified (without our existing workaround)
Without 1c690aa046ebca13d7b29de50d42b5d8a4a8486c IMAGE_ROOTFS_EXTRA_SPACE is ignored
With 1c690aa046ebca13d7b29de50d42b5d8a4a8486c IMAGE_ROOTFS_EXTRA_SPACE is respected