summaryrefslogtreecommitdiffstats
path: root/scripts/lib/wic
diff options
context:
space:
mode:
authorMaciej Borzecki <maciej.borzecki@rndity.com>2016-12-19 12:20:58 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-12-22 08:50:16 +0000
commit1988bae5bfed203ddf889a7def2a49422e5d5e60 (patch)
tree7ea3490a77b1e5cd854480609956a0a489d22339 /scripts/lib/wic
parent5903182484276fec4d9ccbe7ad2c859e9588e5ba (diff)
downloadpoky-1988bae5bfed203ddf889a7def2a49422e5d5e60.tar.gz
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>
Diffstat (limited to 'scripts/lib/wic')
-rw-r--r--scripts/lib/wic/help.py14
-rw-r--r--scripts/lib/wic/imager/direct.py2
-rw-r--r--scripts/lib/wic/ksparser.py41
-rw-r--r--scripts/lib/wic/partition.py88
-rw-r--r--scripts/lib/wic/utils/partitionedfs.py2
5 files changed, 105 insertions, 42 deletions
diff --git a/scripts/lib/wic/help.py b/scripts/lib/wic/help.py
index e5347ec4b7..daa11bf489 100644
--- a/scripts/lib/wic/help.py
+++ b/scripts/lib/wic/help.py
@@ -646,6 +646,12 @@ DESCRIPTION
646 not specified, the size is in MB. 646 not specified, the size is in MB.
647 You do not need this option if you use --source. 647 You do not need this option if you use --source.
648 648
649 --fixed-size: Exact partition size. Value format is the same
650 as for --size option. This option cannot be
651 specified along with --size. If partition data
652 is larger than --fixed-size and error will be
653 raised when assembling disk image.
654
649 --source: This option is a wic-specific option that names the 655 --source: This option is a wic-specific option that names the
650 source of the data that will populate the 656 source of the data that will populate the
651 partition. The most common value for this option 657 partition. The most common value for this option
@@ -719,13 +725,15 @@ DESCRIPTION
719 space after the space filled by the content 725 space after the space filled by the content
720 of the partition. The final size can go 726 of the partition. The final size can go
721 beyond the size specified by --size. 727 beyond the size specified by --size.
722 By default, 10MB. 728 By default, 10MB. This option cannot be used
729 with --fixed-size option.
723 730
724 --overhead-factor: This option is specific to wic. The 731 --overhead-factor: This option is specific to wic. The
725 size of the partition is multiplied by 732 size of the partition is multiplied by
726 this factor. It has to be greater than or 733 this factor. It has to be greater than or
727 equal to 1. 734 equal to 1. The default value is 1.3.
728 The default value is 1.3. 735 This option cannot be used with --fixed-size
736 option.
729 737
730 --part-type: This option is specific to wic. It specifies partition 738 --part-type: This option is specific to wic. It specifies partition
731 type GUID for GPT partitions. 739 type GUID for GPT partitions.
diff --git a/scripts/lib/wic/imager/direct.py b/scripts/lib/wic/imager/direct.py
index 2bedef08d6..11ec15e33f 100644
--- a/scripts/lib/wic/imager/direct.py
+++ b/scripts/lib/wic/imager/direct.py
@@ -290,7 +290,7 @@ class DirectImageCreator(BaseImageCreator):
290 self.bootimg_dir, self.kernel_dir, self.native_sysroot) 290 self.bootimg_dir, self.kernel_dir, self.native_sysroot)
291 291
292 292
293 self.__image.add_partition(int(part.size), 293 self.__image.add_partition(part.disk_size,
294 part.disk, 294 part.disk,
295 part.mountpoint, 295 part.mountpoint,
296 part.source_file, 296 part.source_file,
diff --git a/scripts/lib/wic/ksparser.py b/scripts/lib/wic/ksparser.py
index 0894e2b199..62c490274a 100644
--- a/scripts/lib/wic/ksparser.py
+++ b/scripts/lib/wic/ksparser.py
@@ -113,6 +113,9 @@ def systemidtype(arg):
113class KickStart(): 113class KickStart():
114 """"Kickstart parser implementation.""" 114 """"Kickstart parser implementation."""
115 115
116 DEFAULT_EXTRA_SPACE = 10*1024
117 DEFAULT_OVERHEAD_FACTOR = 1.3
118
116 def __init__(self, confpath): 119 def __init__(self, confpath):
117 120
118 self.partitions = [] 121 self.partitions = []
@@ -127,16 +130,24 @@ class KickStart():
127 part.add_argument('mountpoint', nargs='?') 130 part.add_argument('mountpoint', nargs='?')
128 part.add_argument('--active', action='store_true') 131 part.add_argument('--active', action='store_true')
129 part.add_argument('--align', type=int) 132 part.add_argument('--align', type=int)
130 part.add_argument("--extra-space", type=sizetype, default=10*1024) 133 part.add_argument("--extra-space", type=sizetype)
131 part.add_argument('--fsoptions', dest='fsopts') 134 part.add_argument('--fsoptions', dest='fsopts')
132 part.add_argument('--fstype') 135 part.add_argument('--fstype')
133 part.add_argument('--label') 136 part.add_argument('--label')
134 part.add_argument('--no-table', action='store_true') 137 part.add_argument('--no-table', action='store_true')
135 part.add_argument('--ondisk', '--ondrive', dest='disk') 138 part.add_argument('--ondisk', '--ondrive', dest='disk')
136 part.add_argument("--overhead-factor", type=overheadtype, default=1.3) 139 part.add_argument("--overhead-factor", type=overheadtype)
137 part.add_argument('--part-type') 140 part.add_argument('--part-type')
138 part.add_argument('--rootfs-dir') 141 part.add_argument('--rootfs-dir')
139 part.add_argument('--size', type=sizetype, default=0) 142
143 # --size and --fixed-size cannot be specified together; options
144 # ----extra-space and --overhead-factor should also raise a parser
145 # --error, but since nesting mutually exclusive groups does not work,
146 # ----extra-space/--overhead-factor are handled later
147 sizeexcl = part.add_mutually_exclusive_group()
148 sizeexcl.add_argument('--size', type=sizetype, default=0)
149 sizeexcl.add_argument('--fixed-size', type=sizetype, default=0)
150
140 part.add_argument('--source') 151 part.add_argument('--source')
141 part.add_argument('--sourceparams') 152 part.add_argument('--sourceparams')
142 part.add_argument('--system-id', type=systemidtype) 153 part.add_argument('--system-id', type=systemidtype)
@@ -170,11 +181,33 @@ class KickStart():
170 lineno += 1 181 lineno += 1
171 if line and line[0] != '#': 182 if line and line[0] != '#':
172 try: 183 try:
173 parsed = parser.parse_args(shlex.split(line)) 184 line_args = shlex.split(line)
185 parsed = parser.parse_args(line_args)
174 except ArgumentError as err: 186 except ArgumentError as err:
175 raise KickStartError('%s:%d: %s' % \ 187 raise KickStartError('%s:%d: %s' % \
176 (confpath, lineno, err)) 188 (confpath, lineno, err))
177 if line.startswith('part'): 189 if line.startswith('part'):
190 # using ArgumentParser one cannot easily tell if option
191 # was passed as argument, if said option has a default
192 # value; --overhead-factor/--extra-space cannot be used
193 # with --fixed-size, so at least detect when these were
194 # passed with non-0 values ...
195 if parsed.fixed_size:
196 if parsed.overhead_factor or parsed.extra_space:
197 err = "%s:%d: arguments --overhead-factor and --extra-space not "\
198 "allowed with argument --fixed-size" \
199 % (confpath, lineno)
200 raise KickStartError(err)
201 else:
202 # ... and provide defaults if not using
203 # --fixed-size iff given option was not used
204 # (again, one cannot tell if option was passed but
205 # with value equal to 0)
206 if '--overhead-factor' not in line_args:
207 parsed.overhead_factor = self.DEFAULT_OVERHEAD_FACTOR
208 if '--extra-space' not in line_args:
209 parsed.extra_space = self.DEFAULT_EXTRA_SPACE
210
178 self.partnum += 1 211 self.partnum += 1
179 self.partitions.append(Partition(parsed, self.partnum)) 212 self.partitions.append(Partition(parsed, self.partnum))
180 elif line.startswith('include'): 213 elif line.startswith('include'):
diff --git a/scripts/lib/wic/partition.py b/scripts/lib/wic/partition.py
index b191cdee54..aa8f8a7948 100644
--- a/scripts/lib/wic/partition.py
+++ b/scripts/lib/wic/partition.py
@@ -54,6 +54,7 @@ class Partition():
54 self.part_type = args.part_type 54 self.part_type = args.part_type
55 self.rootfs_dir = args.rootfs_dir 55 self.rootfs_dir = args.rootfs_dir
56 self.size = args.size 56 self.size = args.size
57 self.fixed_size = args.fixed_size
57 self.source = args.source 58 self.source = args.source
58 self.sourceparams = args.sourceparams 59 self.sourceparams = args.sourceparams
59 self.system_id = args.system_id 60 self.system_id = args.system_id
@@ -87,6 +88,41 @@ class Partition():
87 else: 88 else:
88 return 0 89 return 0
89 90
91 def get_rootfs_size(self, actual_rootfs_size=0):
92 """
93 Calculate the required size of rootfs taking into consideration
94 --size/--fixed-size flags as well as overhead and extra space, as
95 specified in kickstart file. Raises an error if the
96 `actual_rootfs_size` is larger than fixed-size rootfs.
97
98 """
99 if self.fixed_size:
100 rootfs_size = self.fixed_size
101 if actual_rootfs_size > rootfs_size:
102 msger.error("Actual rootfs size (%d kB) is larger than allowed size %d kB" \
103 %(actual_rootfs_size, rootfs_size))
104 else:
105 extra_blocks = self.get_extra_block_count(actual_rootfs_size)
106 if extra_blocks < self.extra_space:
107 extra_blocks = self.extra_space
108
109 rootfs_size = actual_rootfs_size + extra_blocks
110 rootfs_size *= self.overhead_factor
111
112 msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
113 (extra_blocks, self.mountpoint, rootfs_size))
114
115 return rootfs_size
116
117 @property
118 def disk_size(self):
119 """
120 Obtain on-disk size of partition taking into consideration
121 --size/--fixed-size options.
122
123 """
124 return self.fixed_size if self.fixed_size else self.size
125
90 def prepare(self, creator, cr_workdir, oe_builddir, rootfs_dir, 126 def prepare(self, creator, cr_workdir, oe_builddir, rootfs_dir,
91 bootimg_dir, kernel_dir, native_sysroot): 127 bootimg_dir, kernel_dir, native_sysroot):
92 """ 128 """
@@ -97,9 +133,9 @@ class Partition():
97 self.sourceparams_dict = parse_sourceparams(self.sourceparams) 133 self.sourceparams_dict = parse_sourceparams(self.sourceparams)
98 134
99 if not self.source: 135 if not self.source:
100 if not self.size: 136 if not self.size and not self.fixed_size:
101 msger.error("The %s partition has a size of zero. Please " 137 msger.error("The %s partition has a size of zero. Please "
102 "specify a non-zero --size for that partition." % \ 138 "specify a non-zero --size/--fixed-size for that partition." % \
103 self.mountpoint) 139 self.mountpoint)
104 if self.fstype and self.fstype == "swap": 140 if self.fstype and self.fstype == "swap":
105 self.prepare_swap_partition(cr_workdir, oe_builddir, 141 self.prepare_swap_partition(cr_workdir, oe_builddir,
@@ -146,6 +182,7 @@ class Partition():
146 oe_builddir, 182 oe_builddir,
147 bootimg_dir, kernel_dir, rootfs_dir, 183 bootimg_dir, kernel_dir, rootfs_dir,
148 native_sysroot) 184 native_sysroot)
185
149 # further processing required Partition.size to be an integer, make 186 # further processing required Partition.size to be an integer, make
150 # sure that it is one 187 # sure that it is one
151 if type(self.size) is not int: 188 if type(self.size) is not int:
@@ -153,6 +190,12 @@ class Partition():
153 "This a bug in source plugin %s and needs to be fixed." \ 190 "This a bug in source plugin %s and needs to be fixed." \
154 % (self.mountpoint, self.source)) 191 % (self.mountpoint, self.source))
155 192
193 if self.fixed_size and self.size > self.fixed_size:
194 msger.error("File system image of partition %s is larger (%d kB) than its"\
195 "allowed size %d kB" % (self.mountpoint,
196 self.size, self.fixed_size))
197
198
156 def prepare_rootfs_from_fs_image(self, cr_workdir, oe_builddir, 199 def prepare_rootfs_from_fs_image(self, cr_workdir, oe_builddir,
157 rootfs_dir): 200 rootfs_dir):
158 """ 201 """
@@ -228,15 +271,7 @@ class Partition():
228 out = exec_cmd(du_cmd) 271 out = exec_cmd(du_cmd)
229 actual_rootfs_size = int(out.split()[0]) 272 actual_rootfs_size = int(out.split()[0])
230 273
231 extra_blocks = self.get_extra_block_count(actual_rootfs_size) 274 rootfs_size = self.get_rootfs_size(actual_rootfs_size)
232 if extra_blocks < self.extra_space:
233 extra_blocks = self.extra_space
234
235 rootfs_size = actual_rootfs_size + extra_blocks
236 rootfs_size *= self.overhead_factor
237
238 msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
239 (extra_blocks, self.mountpoint, rootfs_size))
240 275
241 with open(rootfs, 'w') as sparse: 276 with open(rootfs, 'w') as sparse:
242 os.ftruncate(sparse.fileno(), rootfs_size * 1024) 277 os.ftruncate(sparse.fileno(), rootfs_size * 1024)
@@ -262,15 +297,7 @@ class Partition():
262 out = exec_cmd(du_cmd) 297 out = exec_cmd(du_cmd)
263 actual_rootfs_size = int(out.split()[0]) 298 actual_rootfs_size = int(out.split()[0])
264 299
265 extra_blocks = self.get_extra_block_count(actual_rootfs_size) 300 rootfs_size = self.get_rootfs_size(actual_rootfs_size)
266 if extra_blocks < self.extra_space:
267 extra_blocks = self.extra_space
268
269 rootfs_size = actual_rootfs_size + extra_blocks
270 rootfs_size *= self.overhead_factor
271
272 msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
273 (extra_blocks, self.mountpoint, rootfs_size))
274 301
275 with open(rootfs, 'w') as sparse: 302 with open(rootfs, 'w') as sparse:
276 os.ftruncate(sparse.fileno(), rootfs_size * 1024) 303 os.ftruncate(sparse.fileno(), rootfs_size * 1024)
@@ -292,20 +319,13 @@ class Partition():
292 out = exec_cmd(du_cmd) 319 out = exec_cmd(du_cmd)
293 blocks = int(out.split()[0]) 320 blocks = int(out.split()[0])
294 321
295 extra_blocks = self.get_extra_block_count(blocks) 322 rootfs_size = self.get_rootfs_size(blocks)
296 if extra_blocks < self.extra_space:
297 extra_blocks = self.extra_space
298
299 blocks += extra_blocks
300
301 msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
302 (extra_blocks, self.mountpoint, blocks))
303 323
304 label_str = "-n boot" 324 label_str = "-n boot"
305 if self.label: 325 if self.label:
306 label_str = "-n %s" % self.label 326 label_str = "-n %s" % self.label
307 327
308 dosfs_cmd = "mkdosfs %s -S 512 -C %s %d" % (label_str, rootfs, blocks) 328 dosfs_cmd = "mkdosfs %s -S 512 -C %s %d" % (label_str, rootfs, rootfs_size)
309 exec_native_cmd(dosfs_cmd, native_sysroot) 329 exec_native_cmd(dosfs_cmd, native_sysroot)
310 330
311 mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (rootfs, rootfs_dir) 331 mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (rootfs, rootfs_dir)
@@ -328,8 +348,9 @@ class Partition():
328 """ 348 """
329 Prepare an empty ext2/3/4 partition. 349 Prepare an empty ext2/3/4 partition.
330 """ 350 """
351 size = self.disk_size
331 with open(rootfs, 'w') as sparse: 352 with open(rootfs, 'w') as sparse:
332 os.ftruncate(sparse.fileno(), self.size * 1024) 353 os.ftruncate(sparse.fileno(), size * 1024)
333 354
334 extra_imagecmd = "-i 8192" 355 extra_imagecmd = "-i 8192"
335 356
@@ -346,8 +367,9 @@ class Partition():
346 """ 367 """
347 Prepare an empty btrfs partition. 368 Prepare an empty btrfs partition.
348 """ 369 """
370 size = self.disk_size
349 with open(rootfs, 'w') as sparse: 371 with open(rootfs, 'w') as sparse:
350 os.ftruncate(sparse.fileno(), self.size * 1024) 372 os.ftruncate(sparse.fileno(), size * 1024)
351 373
352 label_str = "" 374 label_str = ""
353 if self.label: 375 if self.label:
@@ -362,7 +384,7 @@ class Partition():
362 """ 384 """
363 Prepare an empty vfat partition. 385 Prepare an empty vfat partition.
364 """ 386 """
365 blocks = self.size 387 blocks = self.disk_size
366 388
367 label_str = "-n boot" 389 label_str = "-n boot"
368 if self.label: 390 if self.label:
diff --git a/scripts/lib/wic/utils/partitionedfs.py b/scripts/lib/wic/utils/partitionedfs.py
index 9ea4a30cbb..68301f0b47 100644
--- a/scripts/lib/wic/utils/partitionedfs.py
+++ b/scripts/lib/wic/utils/partitionedfs.py
@@ -210,7 +210,7 @@ class Image():
210 msger.debug("Assigned %s to %s%d, sectors range %d-%d size %d " 210 msger.debug("Assigned %s to %s%d, sectors range %d-%d size %d "
211 "sectors (%d bytes)." \ 211 "sectors (%d bytes)." \
212 % (part['mountpoint'], part['disk_name'], part['num'], 212 % (part['mountpoint'], part['disk_name'], part['num'],
213 part['start'], part['start'] + part['size'] - 1, 213 part['start'], disk['offset'] - 1,
214 part['size'], part['size'] * self.sector_size)) 214 part['size'], part['size'] * self.sector_size))
215 215
216 # Once all the partitions have been layed out, we can calculate the 216 # Once all the partitions have been layed out, we can calculate the