wic: add --fixed-size wks option

Added new option --fixed-size to wks. The option can be used to indicate
the exact size of a partition. The option cannot be added together with
--size, in which case an error will be raised. Other options that
influence automatic partition size (--extra-space, --overhead-factor),
if specifiec along with --fixed-size, will raise an error.

If it partition data is larger than the amount of space specified with
--fixed-size option wic will raise an error.

(From OE-Core rev: fdd217ba874bd480e0180830fe2e6bd54dde19d9)

Signed-off-by: Maciej Borzecki <maciej.borzecki@rndity.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Maciej Borzecki 2016-12-19 12:20:58 +01:00 committed by Richard Purdie
parent 5903182484
commit 1988bae5bf
5 changed files with 105 additions and 42 deletions

View File

@ -646,6 +646,12 @@ DESCRIPTION
not specified, the size is in MB.
You do not need this option if you use --source.
--fixed-size: Exact partition size. Value format is the same
as for --size option. This option cannot be
specified along with --size. If partition data
is larger than --fixed-size and error will be
raised when assembling disk image.
--source: This option is a wic-specific option that names the
source of the data that will populate the
partition. The most common value for this option
@ -719,13 +725,15 @@ DESCRIPTION
space after the space filled by the content
of the partition. The final size can go
beyond the size specified by --size.
By default, 10MB.
By default, 10MB. This option cannot be used
with --fixed-size option.
--overhead-factor: This option is specific to wic. The
size of the partition is multiplied by
this factor. It has to be greater than or
equal to 1.
The default value is 1.3.
equal to 1. The default value is 1.3.
This option cannot be used with --fixed-size
option.
--part-type: This option is specific to wic. It specifies partition
type GUID for GPT partitions.

View File

@ -290,7 +290,7 @@ class DirectImageCreator(BaseImageCreator):
self.bootimg_dir, self.kernel_dir, self.native_sysroot)
self.__image.add_partition(int(part.size),
self.__image.add_partition(part.disk_size,
part.disk,
part.mountpoint,
part.source_file,

View File

@ -113,6 +113,9 @@ def systemidtype(arg):
class KickStart():
""""Kickstart parser implementation."""
DEFAULT_EXTRA_SPACE = 10*1024
DEFAULT_OVERHEAD_FACTOR = 1.3
def __init__(self, confpath):
self.partitions = []
@ -127,16 +130,24 @@ class KickStart():
part.add_argument('mountpoint', nargs='?')
part.add_argument('--active', action='store_true')
part.add_argument('--align', type=int)
part.add_argument("--extra-space", type=sizetype, default=10*1024)
part.add_argument("--extra-space", type=sizetype)
part.add_argument('--fsoptions', dest='fsopts')
part.add_argument('--fstype')
part.add_argument('--label')
part.add_argument('--no-table', action='store_true')
part.add_argument('--ondisk', '--ondrive', dest='disk')
part.add_argument("--overhead-factor", type=overheadtype, default=1.3)
part.add_argument("--overhead-factor", type=overheadtype)
part.add_argument('--part-type')
part.add_argument('--rootfs-dir')
part.add_argument('--size', type=sizetype, default=0)
# --size and --fixed-size cannot be specified together; options
# ----extra-space and --overhead-factor should also raise a parser
# --error, but since nesting mutually exclusive groups does not work,
# ----extra-space/--overhead-factor are handled later
sizeexcl = part.add_mutually_exclusive_group()
sizeexcl.add_argument('--size', type=sizetype, default=0)
sizeexcl.add_argument('--fixed-size', type=sizetype, default=0)
part.add_argument('--source')
part.add_argument('--sourceparams')
part.add_argument('--system-id', type=systemidtype)
@ -170,11 +181,33 @@ class KickStart():
lineno += 1
if line and line[0] != '#':
try:
parsed = parser.parse_args(shlex.split(line))
line_args = shlex.split(line)
parsed = parser.parse_args(line_args)
except ArgumentError as err:
raise KickStartError('%s:%d: %s' % \
(confpath, lineno, err))
if line.startswith('part'):
# using ArgumentParser one cannot easily tell if option
# was passed as argument, if said option has a default
# value; --overhead-factor/--extra-space cannot be used
# with --fixed-size, so at least detect when these were
# passed with non-0 values ...
if parsed.fixed_size:
if parsed.overhead_factor or parsed.extra_space:
err = "%s:%d: arguments --overhead-factor and --extra-space not "\
"allowed with argument --fixed-size" \
% (confpath, lineno)
raise KickStartError(err)
else:
# ... and provide defaults if not using
# --fixed-size iff given option was not used
# (again, one cannot tell if option was passed but
# with value equal to 0)
if '--overhead-factor' not in line_args:
parsed.overhead_factor = self.DEFAULT_OVERHEAD_FACTOR
if '--extra-space' not in line_args:
parsed.extra_space = self.DEFAULT_EXTRA_SPACE
self.partnum += 1
self.partitions.append(Partition(parsed, self.partnum))
elif line.startswith('include'):

View File

@ -54,6 +54,7 @@ class Partition():
self.part_type = args.part_type
self.rootfs_dir = args.rootfs_dir
self.size = args.size
self.fixed_size = args.fixed_size
self.source = args.source
self.sourceparams = args.sourceparams
self.system_id = args.system_id
@ -87,6 +88,41 @@ class Partition():
else:
return 0
def get_rootfs_size(self, actual_rootfs_size=0):
"""
Calculate the required size of rootfs taking into consideration
--size/--fixed-size flags as well as overhead and extra space, as
specified in kickstart file. Raises an error if the
`actual_rootfs_size` is larger than fixed-size rootfs.
"""
if self.fixed_size:
rootfs_size = self.fixed_size
if actual_rootfs_size > rootfs_size:
msger.error("Actual rootfs size (%d kB) is larger than allowed size %d kB" \
%(actual_rootfs_size, rootfs_size))
else:
extra_blocks = self.get_extra_block_count(actual_rootfs_size)
if extra_blocks < self.extra_space:
extra_blocks = self.extra_space
rootfs_size = actual_rootfs_size + extra_blocks
rootfs_size *= self.overhead_factor
msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
(extra_blocks, self.mountpoint, rootfs_size))
return rootfs_size
@property
def disk_size(self):
"""
Obtain on-disk size of partition taking into consideration
--size/--fixed-size options.
"""
return self.fixed_size if self.fixed_size else self.size
def prepare(self, creator, cr_workdir, oe_builddir, rootfs_dir,
bootimg_dir, kernel_dir, native_sysroot):
"""
@ -97,9 +133,9 @@ class Partition():
self.sourceparams_dict = parse_sourceparams(self.sourceparams)
if not self.source:
if not self.size:
msger.error("The %s partition has a size of zero. Please "
"specify a non-zero --size for that partition." % \
if not self.size and not self.fixed_size:
msger.error("The %s partition has a size of zero. Please "
"specify a non-zero --size/--fixed-size for that partition." % \
self.mountpoint)
if self.fstype and self.fstype == "swap":
self.prepare_swap_partition(cr_workdir, oe_builddir,
@ -146,6 +182,7 @@ class Partition():
oe_builddir,
bootimg_dir, kernel_dir, rootfs_dir,
native_sysroot)
# further processing required Partition.size to be an integer, make
# sure that it is one
if type(self.size) is not int:
@ -153,6 +190,12 @@ class Partition():
"This a bug in source plugin %s and needs to be fixed." \
% (self.mountpoint, self.source))
if self.fixed_size and self.size > self.fixed_size:
msger.error("File system image of partition %s is larger (%d kB) than its"\
"allowed size %d kB" % (self.mountpoint,
self.size, self.fixed_size))
def prepare_rootfs_from_fs_image(self, cr_workdir, oe_builddir,
rootfs_dir):
"""
@ -228,15 +271,7 @@ class Partition():
out = exec_cmd(du_cmd)
actual_rootfs_size = int(out.split()[0])
extra_blocks = self.get_extra_block_count(actual_rootfs_size)
if extra_blocks < self.extra_space:
extra_blocks = self.extra_space
rootfs_size = actual_rootfs_size + extra_blocks
rootfs_size *= self.overhead_factor
msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
(extra_blocks, self.mountpoint, rootfs_size))
rootfs_size = self.get_rootfs_size(actual_rootfs_size)
with open(rootfs, 'w') as sparse:
os.ftruncate(sparse.fileno(), rootfs_size * 1024)
@ -262,15 +297,7 @@ class Partition():
out = exec_cmd(du_cmd)
actual_rootfs_size = int(out.split()[0])
extra_blocks = self.get_extra_block_count(actual_rootfs_size)
if extra_blocks < self.extra_space:
extra_blocks = self.extra_space
rootfs_size = actual_rootfs_size + extra_blocks
rootfs_size *= self.overhead_factor
msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
(extra_blocks, self.mountpoint, rootfs_size))
rootfs_size = self.get_rootfs_size(actual_rootfs_size)
with open(rootfs, 'w') as sparse:
os.ftruncate(sparse.fileno(), rootfs_size * 1024)
@ -292,20 +319,13 @@ class Partition():
out = exec_cmd(du_cmd)
blocks = int(out.split()[0])
extra_blocks = self.get_extra_block_count(blocks)
if extra_blocks < self.extra_space:
extra_blocks = self.extra_space
blocks += extra_blocks
msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
(extra_blocks, self.mountpoint, blocks))
rootfs_size = self.get_rootfs_size(blocks)
label_str = "-n boot"
if self.label:
label_str = "-n %s" % self.label
dosfs_cmd = "mkdosfs %s -S 512 -C %s %d" % (label_str, rootfs, blocks)
dosfs_cmd = "mkdosfs %s -S 512 -C %s %d" % (label_str, rootfs, rootfs_size)
exec_native_cmd(dosfs_cmd, native_sysroot)
mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (rootfs, rootfs_dir)
@ -328,8 +348,9 @@ class Partition():
"""
Prepare an empty ext2/3/4 partition.
"""
size = self.disk_size
with open(rootfs, 'w') as sparse:
os.ftruncate(sparse.fileno(), self.size * 1024)
os.ftruncate(sparse.fileno(), size * 1024)
extra_imagecmd = "-i 8192"
@ -346,8 +367,9 @@ class Partition():
"""
Prepare an empty btrfs partition.
"""
size = self.disk_size
with open(rootfs, 'w') as sparse:
os.ftruncate(sparse.fileno(), self.size * 1024)
os.ftruncate(sparse.fileno(), size * 1024)
label_str = ""
if self.label:
@ -362,7 +384,7 @@ class Partition():
"""
Prepare an empty vfat partition.
"""
blocks = self.size
blocks = self.disk_size
label_str = "-n boot"
if self.label:

View File

@ -210,7 +210,7 @@ class Image():
msger.debug("Assigned %s to %s%d, sectors range %d-%d size %d "
"sectors (%d bytes)." \
% (part['mountpoint'], part['disk_name'], part['num'],
part['start'], part['start'] + part['size'] - 1,
part['start'], disk['offset'] - 1,
part['size'], part['size'] * self.sector_size))
# Once all the partitions have been layed out, we can calculate the