All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ed Bartosh <ed.bartosh@linux.intel.com>
To: Maciej Borzecki <maciej.borzecki@rndity.com>
Cc: Maciej Borzecki <maciek.borzecki@gmail.com>,
	openembedded-core@lists.openembedded.org
Subject: Re: [PATCH 5/5] wic: add --fixed-size wks option
Date: Wed, 9 Nov 2016 11:36:27 +0200	[thread overview]
Message-ID: <20161109093627.GB10823@linux.intel.com> (raw)
In-Reply-To: <1135a635b723fcf1eb2ce8d2b9f8463a577f6acd.1478619682.git.maciej.borzecki@rndity.com>

On Tue, Nov 08, 2016 at 04:56:11PM +0100, Maciej Borzecki wrote:
> 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.
> 
> Signed-off-by: Maciej Borzecki <maciej.borzecki@rndity.com>
> ---
>  scripts/lib/wic/help.py                | 14 ++++--
>  scripts/lib/wic/imager/direct.py       |  2 +-
>  scripts/lib/wic/ksparser.py            | 41 +++++++++++++++--
>  scripts/lib/wic/partition.py           | 83 ++++++++++++++++++++--------------
>  scripts/lib/wic/utils/partitionedfs.py |  2 +-
>  5 files changed, 100 insertions(+), 42 deletions(-)
> 
> diff --git a/scripts/lib/wic/help.py b/scripts/lib/wic/help.py
> index e5347ec4b7c900c68fc64351a5293e75de0672b3..daa11bf489c135627ddfe4cef968e48f8e3ad1d8 100644
> --- a/scripts/lib/wic/help.py
> +++ b/scripts/lib/wic/help.py
> @@ -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.
> diff --git a/scripts/lib/wic/imager/direct.py b/scripts/lib/wic/imager/direct.py
> index 2bedef08d6450096c786def6f75a9ee53fcd4b3b..c01a1ea538428e36a75ac5b31a822e01901bea6a 100644
> --- a/scripts/lib/wic/imager/direct.py
> +++ b/scripts/lib/wic/imager/direct.py
> @@ -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.get_size(),
>                                         part.disk,
>                                         part.mountpoint,
>                                         part.source_file,
> diff --git a/scripts/lib/wic/ksparser.py b/scripts/lib/wic/ksparser.py
> index 0894e2b199a299fbbed272f2e1c95e9d692e3ab1..62c490274aa92bf82aac304d9323250e3b728d0c 100644
> --- a/scripts/lib/wic/ksparser.py
> +++ b/scripts/lib/wic/ksparser.py
> @@ -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 ...
I'd suggest to handle this using argparse mutual exclusion:
https://docs.python.org/2/library/argparse.html#mutual-exclusion

> +                        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'):
> diff --git a/scripts/lib/wic/partition.py b/scripts/lib/wic/partition.py
> index 24e657592738dc7c5cdff78e3740d7c373021e9d..354d4b44c50c77baa54331e95ce0876c32d09339 100644
> --- a/scripts/lib/wic/partition.py
> +++ b/scripts/lib/wic/partition.py
> @@ -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,39 @@ 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
> +
> +    def get_size(self):
> +        """
> +        Obtain partition size 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):
Can you make self.size and self.fixed_size getters as properties(use @property decorator)?
It should make code look more pythonic.

>          """
> @@ -97,9 +131,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 +180,10 @@ class Partition():
>                                                       oe_builddir,
>                                                       bootimg_dir, kernel_dir, rootfs_dir,
>                                                       native_sysroot)
> +        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):
> @@ -211,15 +249,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)
> @@ -245,15 +275,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)
> @@ -275,20 +297,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)
> @@ -311,8 +326,9 @@ class Partition():
>          """
>          Prepare an empty ext2/3/4 partition.
>          """
> +        size = self.get_size()
>          with open(rootfs, 'w') as sparse:
> -            os.ftruncate(sparse.fileno(), self.size * 1024)
> +            os.ftruncate(sparse.fileno(), size * 1024)
>  
>          extra_imagecmd = "-i 8192"
>  
> @@ -329,8 +345,9 @@ class Partition():
>          """
>          Prepare an empty btrfs partition.
>          """
> +        size = self.get_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:
> @@ -345,7 +362,7 @@ class Partition():
>          """
>          Prepare an empty vfat partition.
>          """
> -        blocks = self.size
> +        blocks = self.get_size()
>  
>          label_str = "-n boot"
>          if self.label:
> diff --git a/scripts/lib/wic/utils/partitionedfs.py b/scripts/lib/wic/utils/partitionedfs.py
> index 9e76487844eebfffc7227d053a65dc9fdab3678b..cfa5f5ce09b764c1c2a9b7a3f7bf7d677a6811c4 100644
> --- a/scripts/lib/wic/utils/partitionedfs.py
> +++ b/scripts/lib/wic/utils/partitionedfs.py
> @@ -209,7 +209,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
> -- 
> 2.5.0
> 

-- 
--
Regards,
Ed


  reply	other threads:[~2016-11-09  9:36 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-11-08 15:56 [PATCH 0/5] wic: bugfixes & --fixed-size support Maciej Borzecki
2016-11-08 15:56 ` [PATCH 1/5] wic: make sure that partition size is always an integer in internal processing Maciej Borzecki
2016-11-08 15:56 ` [PATCH 2/5] wic: use partition size when creating empty partition files Maciej Borzecki
2016-11-09  9:23   ` Ed Bartosh
2016-11-08 15:56 ` [PATCH 3/5] wic: check that filesystem is specified for a rootfs partition Maciej Borzecki
2016-11-09  9:44   ` Ed Bartosh
2016-11-09 10:42     ` Maciej Borzęcki
2016-11-08 15:56 ` [PATCH 4/5] wic: fix function comment typos Maciej Borzecki
2016-11-08 15:56 ` [PATCH 5/5] wic: add --fixed-size wks option Maciej Borzecki
2016-11-09  9:36   ` Ed Bartosh [this message]
2016-11-09 12:08     ` Maciej Borzęcki
2016-11-09  9:39 ` [PATCH 0/5] wic: bugfixes & --fixed-size support Ed Bartosh
2016-11-09 13:17 ` Burton, Ross
2016-11-09 13:49   ` Maciej Borzęcki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20161109093627.GB10823@linux.intel.com \
    --to=ed.bartosh@linux.intel.com \
    --cc=maciej.borzecki@rndity.com \
    --cc=maciek.borzecki@gmail.com \
    --cc=openembedded-core@lists.openembedded.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.