diff options
author | Trevor Woerner <twoerner@gmail.com> | 2025-04-14 22:04:05 -0400 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2025-04-17 11:03:22 +0100 |
commit | 35807e8f634ce86bc77b3461cb0deb466c08a9d2 (patch) | |
tree | b5f2e19ef78881b5fdd8d2f5a68ea2a7eb9d63dc | |
parent | 94d2759dd72c2e26ccecea072ecac4831671f00b (diff) | |
download | poky-35807e8f634ce86bc77b3461cb0deb466c08a9d2.tar.gz |
wic: do not ignore ROOTFS_SIZE if the rootfs is modified
If the *.wks file contains a "--source rootfs" then
lib/wic/plugins/source/rootfs.py will be invoked to generate (what is assumed
to be) the rootfs partition. If the rootfs partition needs to be tweaked or
modified, the "rootfs.py" plugin will make a copy of the filesystem and then
perform the changes on that 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 is modified.
If, for example, the unmodified IMAGE_ROOTFS is:
.../tmp/work/qemuarm64_secureboot-oe-linux/core-image-base/1.0/rootfs
then 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 make 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 size 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 other partitions), the code also
verifies that the partition being created 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">
As noted above, if lib/wic/plugins/source/rootfs.py has made a copy, then the
"rdir == rootfs_dir" clause will fail and the code will assume this partition
is not a rootfs since the strings do not compare equal.
Therefore, in order to determine if this is a rootfs, retain the existing
"rdir == rootfs_dir" comparison, but also add another one to check whether or
not this is a wic-generated copy of the rootfs.
STEPS TO REPRODUCE:
- start with the following *wks file:
bootloader --ptable gpt
part /boot --size=100M --active --fstype=ext4 --label boot
part / --source rootfs --fstype=ext4 --label root
- and the following extra variable in conf/local.conf:
IMAGE_ROOTFS_EXTRA_SPACE = "500000"
- build an image
- run it in qemu
$ runqemu slirp nographic serial
- 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
- modify the "/" line of the *wks file to be:
part / --source rootfs --fstype=ext4 --label root --exclude-path boot/
- build image
when it fails:
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
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 the /boot partition is ~20MB and in the first image
the / partition contains this ~20MB in addition to the rest of the rootfs.
This ~20MB is completely wasted since it is used in the / partition, but then
the /boot partition is mounted on top of it, making the /boot directory of /
inaccessible. After the fix the / partition has an additional ~20MB since the
/boot portion is excluded.
Fixes [YOCTO #15555]
(From OE-Core rev: 1c690aa046ebca13d7b29de50d42b5d8a4a8486c)
Signed-off-by: Trevor Woerner <twoerner@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r-- | meta/lib/oeqa/selftest/cases/wic.py | 33 | ||||
-rw-r--r-- | scripts/lib/wic/partition.py | 2 |
2 files changed, 34 insertions, 1 deletions
diff --git a/meta/lib/oeqa/selftest/cases/wic.py b/meta/lib/oeqa/selftest/cases/wic.py index 59fd99a788..d98af8713a 100644 --- a/meta/lib/oeqa/selftest/cases/wic.py +++ b/meta/lib/oeqa/selftest/cases/wic.py | |||
@@ -535,6 +535,39 @@ part /mnt --source rootfs --ondisk mmcblk0 --fstype=ext4 --exclude-path bin/whoa | |||
535 | finally: | 535 | finally: |
536 | os.environ['PATH'] = oldpath | 536 | os.environ['PATH'] = oldpath |
537 | 537 | ||
538 | def test_exclude_path_with_extra_space(self): | ||
539 | """Test having --exclude-path with IMAGE_ROOTFS_EXTRA_SPACE. [Yocto #15555]""" | ||
540 | |||
541 | with NamedTemporaryFile("w", suffix=".wks") as wks: | ||
542 | wks.writelines( | ||
543 | ['bootloader --ptable gpt\n', | ||
544 | 'part /boot --size=100M --active --fstype=ext4 --label boot\n', | ||
545 | 'part / --source rootfs --fstype=ext4 --label root --exclude-path boot/\n']) | ||
546 | wks.flush() | ||
547 | config = 'IMAGE_ROOTFS_EXTRA_SPACE = "500000"\n'\ | ||
548 | 'DEPENDS:pn-core-image-minimal += "wic-tools"\n'\ | ||
549 | 'IMAGE_FSTYPES += "wic"\n'\ | ||
550 | 'WKS_FILE = "%s"\n' % wks.name | ||
551 | self.append_config(config) | ||
552 | bitbake('core-image-minimal') | ||
553 | |||
554 | """ | ||
555 | the output of "wic ls <image>.wic" will look something like: | ||
556 | Num Start End Size Fstype | ||
557 | 1 17408 136332287 136314880 ext4 | ||
558 | 2 136332288 171464703 35132416 ext4 | ||
559 | we are looking for the size of partition 2 | ||
560 | i.e. in this case the number 35,132,416 | ||
561 | without the fix the size will be around 85,403,648 | ||
562 | with the fix the size should be around 799,960,064 | ||
563 | """ | ||
564 | bb_vars = get_bb_vars(['DEPLOY_DIR_IMAGE', 'MACHINE'], 'core-image-minimal') | ||
565 | deploy_dir = bb_vars['DEPLOY_DIR_IMAGE'] | ||
566 | machine = bb_vars['MACHINE'] | ||
567 | wicout = glob(os.path.join(deploy_dir, "core-image-minimal-%s.rootfs-*.wic" % machine))[0] | ||
568 | size_of_root_partition = int(runCmd("wic ls %s" % wicout).output.split('\n')[2].split()[3]) | ||
569 | self.assertGreater(size_of_root_partition, 500000000) | ||
570 | |||
538 | def test_include_path(self): | 571 | def test_include_path(self): |
539 | """Test --include-path wks option.""" | 572 | """Test --include-path wks option.""" |
540 | 573 | ||
diff --git a/scripts/lib/wic/partition.py b/scripts/lib/wic/partition.py index bf2c34d594..b18431d8fb 100644 --- a/scripts/lib/wic/partition.py +++ b/scripts/lib/wic/partition.py | |||
@@ -244,7 +244,7 @@ class Partition(): | |||
244 | # from bitbake variable | 244 | # from bitbake variable |
245 | rsize_bb = get_bitbake_var('ROOTFS_SIZE') | 245 | rsize_bb = get_bitbake_var('ROOTFS_SIZE') |
246 | rdir = get_bitbake_var('IMAGE_ROOTFS') | 246 | rdir = get_bitbake_var('IMAGE_ROOTFS') |
247 | if rsize_bb and rdir == rootfs_dir: | 247 | if rsize_bb and (rdir == rootfs_dir or (rootfs_dir.split('/')[-2] == "tmp-wic" and rootfs_dir.split('/')[-1][:6] == "rootfs")): |
248 | # Bitbake variable ROOTFS_SIZE is calculated in | 248 | # Bitbake variable ROOTFS_SIZE is calculated in |
249 | # Image._get_rootfs_size method from meta/lib/oe/image.py | 249 | # Image._get_rootfs_size method from meta/lib/oe/image.py |
250 | # using IMAGE_ROOTFS_SIZE, IMAGE_ROOTFS_ALIGNMENT, | 250 | # using IMAGE_ROOTFS_SIZE, IMAGE_ROOTFS_ALIGNMENT, |