1
0
mirror of https://git.yoctoproject.org/poky synced 2026-07-16 15:57:04 +00:00

wic: add --extra-partition-space option to set unused space

By default, the content of the partition is filled by the filesystem
without leaving any unused free space. The --extra-space flag adds
extra space to the filesystem size, not to the partition.

Unused free space after the filesystem can be useful for some cases,
such as encrypting a partition at runtime.
With --extra-partition-space 32M, we ensure that the last 32M of the
partition is unused: this space does not contain filesystem data and
can store the LUKS2 header.

The implementation sets a difference between the partition and
filesystem size:
  - With --fixed-size, the extra part space is removed from the
    filesystem size.
  - Otherwise (with or without --size flag), the extra part space is
    added to the partition size.

(From OE-Core rev: 22fd1702aedf40257aa53963b62b5ef1bbd2818a)

Signed-off-by: Pierre-Loup GOSSE <pierre-loup.gosse@smile.fr>

CC: Alexander Kanavin <alex.kanavin@gmail.com>
CC: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Pierre-Loup GOSSE
2025-09-03 16:45:27 +02:00
committed by Richard Purdie
parent 857bb50a35
commit 21d98bd960
4 changed files with 79 additions and 15 deletions
+47 -2
View File
@@ -1166,7 +1166,7 @@ run_wic_cmd() {
return wkspath return wkspath
def _get_wic_partitions(self, wkspath, native_sysroot=None, ignore_status=False): def _get_wic(self, wkspath, ignore_status=False):
p = runCmd("wic create %s -e core-image-minimal -o %s" % (wkspath, self.resultdir), p = runCmd("wic create %s -e core-image-minimal -o %s" % (wkspath, self.resultdir),
ignore_status=ignore_status) ignore_status=ignore_status)
@@ -1180,7 +1180,13 @@ run_wic_cmd() {
if not wicout: if not wicout:
return (p, None) return (p, None)
wicimg = wicout[0] return (p, wicout[0])
def _get_wic_partitions(self, wkspath, native_sysroot=None, ignore_status=False):
p, wicimg = self._get_wic(wkspath, ignore_status)
if wicimg is None:
return (p, None)
if not native_sysroot: if not native_sysroot:
native_sysroot = get_bb_var("RECIPE_SYSROOT_NATIVE", "wic-tools") native_sysroot = get_bb_var("RECIPE_SYSROOT_NATIVE", "wic-tools")
@@ -1320,6 +1326,45 @@ run_wic_cmd() {
size = int(size[:-3]) size = int(size[:-3])
self.assertGreaterEqual(size, 204800) self.assertGreaterEqual(size, 204800)
def test_extra_partition_space(self):
native_sysroot = get_bb_var("RECIPE_SYSROOT_NATIVE", "wic-tools")
with NamedTemporaryFile("w", suffix=".wks") as tempf:
tempf.write("bootloader --ptable gpt\n" \
"part --ondisk hda --size 10M --extra-partition-space 10M --fstype=ext4\n" \
"part --ondisk hda --fixed-size 20M --extra-partition-space 10M --fstype=ext4\n" \
"part --source rootfs --ondisk hda --extra-partition-space 10M --fstype=ext4\n" \
"part --source rootfs --ondisk hda --fixed-size 200M --extra-partition-space 10M --fstype=ext4\n")
tempf.flush()
_, wicimg = self._get_wic(tempf.name)
res = runCmd("parted -m %s unit b p" % wicimg,
native_sysroot=native_sysroot, stderr=subprocess.PIPE)
# parse parted output which looks like this:
# BYT;\n
# /var/tmp/wic/build/tmpfwvjjkf_-201611101222-hda.direct:200MiB:file:512:512:msdos::;\n
# 1:0.00MiB:200MiB:200MiB:ext4::;\n
partlns = res.output.splitlines()[2:]
self.assertEqual(4, len(partlns))
# Test for each partitions that the extra part space exists
for part in range(0, len(partlns)):
part_file = os.path.join(self.resultdir, "selftest_img.part%d" % (part + 1))
partln = partlns[part].split(":")
self.assertEqual(7, len(partln))
self.assertRegex(partln[3], r'^[0-9]+B$')
part_size = int(partln[3].rstrip("B"))
start = int(partln[1].rstrip("B")) / 512
length = part_size / 512
runCmd("dd if=%s of=%s skip=%d count=%d" %
(wicimg, part_file, start, length))
res = runCmd("dumpe2fs %s -h | grep \"^Block count\"" % part_file)
fs_size = int(res.output.split(":")[1].strip()) * 1024
self.assertLessEqual(fs_size + 10485760, part_size, "part file: %s" % part_file)
# TODO this test could also work on aarch64 # TODO this test could also work on aarch64
@skipIfNotArch(['i586', 'i686', 'x86_64']) @skipIfNotArch(['i586', 'i686', 'x86_64'])
@OETestTag("runqemu") @OETestTag("runqemu")
+8
View File
@@ -1020,6 +1020,14 @@ DESCRIPTION
By default, 10MB. This option cannot be used By default, 10MB. This option cannot be used
with --fixed-size option. with --fixed-size option.
--extra-partition-space: This option is specific to wic. It adds extra
empty space after the space filled by the
filesystem. With --fixed-size, the extra
partition space is removed from the filesystem
size. Otherwise (with or without --size flag),
the extra partition space is added to the final
paritition size. The default value is 0MB.
--overhead-factor: This option is specific to wic. The --overhead-factor: This option is specific to wic. The
size of the partition is multiplied by size of the partition is multiplied by
this factor. It has to be greater than or this factor. It has to be greater than or
+3
View File
@@ -154,6 +154,7 @@ class KickStart():
part.add_argument('--include-path', nargs='+', action='append') part.add_argument('--include-path', nargs='+', action='append')
part.add_argument('--change-directory') part.add_argument('--change-directory')
part.add_argument("--extra-space", type=sizetype("M")) part.add_argument("--extra-space", type=sizetype("M"))
part.add_argument('--extra-partition-space', type=sizetype("M"))
part.add_argument('--fsoptions', dest='fsopts') part.add_argument('--fsoptions', dest='fsopts')
part.add_argument('--fspassno', dest='fspassno') part.add_argument('--fspassno', dest='fspassno')
part.add_argument('--fstype', default='vfat', part.add_argument('--fstype', default='vfat',
@@ -259,6 +260,8 @@ class KickStart():
err = "%s:%d: Must set the label with --label" \ err = "%s:%d: Must set the label with --label" \
% (confpath, lineno) % (confpath, lineno)
raise KickStartError(err) raise KickStartError(err)
if not parsed.extra_partition_space:
parsed.extra_partition_space = 0
# using ArgumentParser one cannot easily tell if option # using ArgumentParser one cannot easily tell if option
# was passed as argument, if said option has a default # was passed as argument, if said option has a default
# value; --overhead-factor/--extra-space cannot be used # value; --overhead-factor/--extra-space cannot be used
+21 -13
View File
@@ -29,6 +29,7 @@ class Partition():
self.disk = args.disk self.disk = args.disk
self.device = None self.device = None
self.extra_space = args.extra_space self.extra_space = args.extra_space
self.extra_partition_space = args.extra_partition_space
self.exclude_path = args.exclude_path self.exclude_path = args.exclude_path
self.include_path = args.include_path self.include_path = args.include_path
self.change_directory = args.change_directory self.change_directory = args.change_directory
@@ -91,13 +92,12 @@ class Partition():
def get_rootfs_size(self, actual_rootfs_size=0): def get_rootfs_size(self, actual_rootfs_size=0):
""" """
Calculate the required size of rootfs taking into consideration Calculate the required size of rootfs taking into consideration
--size/--fixed-size flags as well as overhead and extra space, as --size/--fixed-size and --extra-partition-space flags as well as overhead
specified in kickstart file. Raises an error if the and extra space, as specified in kickstart file. Raises an error
`actual_rootfs_size` is larger than fixed-size rootfs. if the `actual_rootfs_size` is larger than fixed-size rootfs.
""" """
if self.fixed_size: if self.fixed_size:
rootfs_size = self.fixed_size rootfs_size = self.fixed_size - self.extra_partition_space
if actual_rootfs_size > rootfs_size: if actual_rootfs_size > rootfs_size:
raise WicError("Actual rootfs size (%d kB) is larger than " raise WicError("Actual rootfs size (%d kB) is larger than "
"allowed size %d kB" % "allowed size %d kB" %
@@ -119,10 +119,18 @@ class Partition():
def disk_size(self): def disk_size(self):
""" """
Obtain on-disk size of partition taking into consideration Obtain on-disk size of partition taking into consideration
--size/--fixed-size options. --size/--fixed-size and --extra-partition-space options.
""" """
return self.fixed_size if self.fixed_size else self.size return self.fixed_size if self.fixed_size else self.size + self.extra_partition_space
@property
def fs_size(self):
"""
Obtain on-disk size of filesystem inside the partition taking into
consideration --size/--fixed-size and --extra-partition-space options.
"""
return self.fixed_size - self.extra_partition_space if self.fixed_size else self.size
def prepare(self, creator, cr_workdir, oe_builddir, rootfs_dir, def prepare(self, creator, cr_workdir, oe_builddir, rootfs_dir,
bootimg_dir, kernel_dir, native_sysroot, updated_fstab_path): bootimg_dir, kernel_dir, native_sysroot, updated_fstab_path):
@@ -202,10 +210,10 @@ class Partition():
"This a bug in source plugin %s and needs to be fixed." % "This a bug in source plugin %s and needs to be fixed." %
(self.mountpoint, self.source)) (self.mountpoint, self.source))
if self.fixed_size and self.size > self.fixed_size: if self.fixed_size and self.size + self.extra_partition_space > self.fixed_size:
raise WicError("File system image of partition %s is " raise WicError("File system image of partition %s is "
"larger (%d kB) than its allowed size %d kB" % "larger (%d kB + %d kB extra part space) than its allowed size %d kB" %
(self.mountpoint, self.size, self.fixed_size)) (self.mountpoint, self.size, self.extra_partition_space, self.fixed_size))
def prepare_rootfs(self, cr_workdir, oe_builddir, rootfs_dir, def prepare_rootfs(self, cr_workdir, oe_builddir, rootfs_dir,
native_sysroot, real_rootfs = True, pseudo_dir = None): native_sysroot, real_rootfs = True, pseudo_dir = None):
@@ -440,7 +448,7 @@ class Partition():
""" """
Prepare an empty ext2/3/4 partition. Prepare an empty ext2/3/4 partition.
""" """
size = self.disk_size size = self.fs_size
with open(rootfs, 'w') as sparse: with open(rootfs, 'w') as sparse:
os.ftruncate(sparse.fileno(), size * 1024) os.ftruncate(sparse.fileno(), size * 1024)
@@ -464,7 +472,7 @@ class Partition():
""" """
Prepare an empty btrfs partition. Prepare an empty btrfs partition.
""" """
size = self.disk_size size = self.fs_size
with open(rootfs, 'w') as sparse: with open(rootfs, 'w') as sparse:
os.ftruncate(sparse.fileno(), size * 1024) os.ftruncate(sparse.fileno(), size * 1024)
@@ -482,7 +490,7 @@ class Partition():
""" """
Prepare an empty vfat partition. Prepare an empty vfat partition.
""" """
blocks = self.disk_size blocks = self.fs_size
label_str = "-n boot" label_str = "-n boot"
if self.label: if self.label: