diff options
Diffstat (limited to 'scripts/lib/wic/partition.py')
-rw-r--r-- | scripts/lib/wic/partition.py | 82 |
1 files changed, 75 insertions, 7 deletions
diff --git a/scripts/lib/wic/partition.py b/scripts/lib/wic/partition.py index ebe250b00d..85f9847047 100644 --- a/scripts/lib/wic/partition.py +++ b/scripts/lib/wic/partition.py | |||
@@ -54,6 +54,9 @@ class Partition(): | |||
54 | self.uuid = args.uuid | 54 | self.uuid = args.uuid |
55 | self.fsuuid = args.fsuuid | 55 | self.fsuuid = args.fsuuid |
56 | self.type = args.type | 56 | self.type = args.type |
57 | self.updated_fstab_path = None | ||
58 | self.has_fstab = False | ||
59 | self.update_fstab_in_rootfs = False | ||
57 | 60 | ||
58 | self.lineno = lineno | 61 | self.lineno = lineno |
59 | self.source_file = "" | 62 | self.source_file = "" |
@@ -118,11 +121,15 @@ class Partition(): | |||
118 | return self.fixed_size if self.fixed_size else self.size | 121 | return self.fixed_size if self.fixed_size else self.size |
119 | 122 | ||
120 | def prepare(self, creator, cr_workdir, oe_builddir, rootfs_dir, | 123 | def prepare(self, creator, cr_workdir, oe_builddir, rootfs_dir, |
121 | bootimg_dir, kernel_dir, native_sysroot): | 124 | bootimg_dir, kernel_dir, native_sysroot, updated_fstab_path): |
122 | """ | 125 | """ |
123 | Prepare content for individual partitions, depending on | 126 | Prepare content for individual partitions, depending on |
124 | partition command parameters. | 127 | partition command parameters. |
125 | """ | 128 | """ |
129 | self.updated_fstab_path = updated_fstab_path | ||
130 | if self.updated_fstab_path and not (self.fstype.startswith("ext") or self.fstype == "msdos"): | ||
131 | self.update_fstab_in_rootfs = True | ||
132 | |||
126 | if not self.source: | 133 | if not self.source: |
127 | if not self.size and not self.fixed_size: | 134 | if not self.size and not self.fixed_size: |
128 | raise WicError("The %s partition has a size of zero. Please " | 135 | raise WicError("The %s partition has a size of zero. Please " |
@@ -207,11 +214,21 @@ class Partition(): | |||
207 | 214 | ||
208 | p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" % native_sysroot) | 215 | p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" % native_sysroot) |
209 | if (pseudo_dir): | 216 | if (pseudo_dir): |
217 | # Canonicalize the ignore paths. This corresponds to | ||
218 | # calling oe.path.canonicalize(), which is used in bitbake.conf. | ||
219 | ignore_paths = [rootfs] + (get_bitbake_var("PSEUDO_IGNORE_PATHS") or "").split(",") | ||
220 | canonical_paths = [] | ||
221 | for path in ignore_paths: | ||
222 | if "$" not in path: | ||
223 | trailing_slash = path.endswith("/") and "/" or "" | ||
224 | canonical_paths.append(os.path.realpath(path) + trailing_slash) | ||
225 | ignore_paths = ",".join(canonical_paths) | ||
226 | |||
210 | pseudo = "export PSEUDO_PREFIX=%s;" % p_prefix | 227 | pseudo = "export PSEUDO_PREFIX=%s;" % p_prefix |
211 | pseudo += "export PSEUDO_LOCALSTATEDIR=%s;" % pseudo_dir | 228 | pseudo += "export PSEUDO_LOCALSTATEDIR=%s;" % pseudo_dir |
212 | pseudo += "export PSEUDO_PASSWD=%s;" % rootfs_dir | 229 | pseudo += "export PSEUDO_PASSWD=%s;" % rootfs_dir |
213 | pseudo += "export PSEUDO_NOSYMLINKEXP=1;" | 230 | pseudo += "export PSEUDO_NOSYMLINKEXP=1;" |
214 | pseudo += "export PSEUDO_IGNORE_PATHS=%s;" % (rootfs + "," + (get_bitbake_var("PSEUDO_IGNORE_PATHS") or "")) | 231 | pseudo += "export PSEUDO_IGNORE_PATHS=%s;" % ignore_paths |
215 | pseudo += "%s " % get_bitbake_var("FAKEROOTCMD") | 232 | pseudo += "%s " % get_bitbake_var("FAKEROOTCMD") |
216 | else: | 233 | else: |
217 | pseudo = None | 234 | pseudo = None |
@@ -237,7 +254,7 @@ class Partition(): | |||
237 | 254 | ||
238 | prefix = "ext" if self.fstype.startswith("ext") else self.fstype | 255 | prefix = "ext" if self.fstype.startswith("ext") else self.fstype |
239 | method = getattr(self, "prepare_rootfs_" + prefix) | 256 | method = getattr(self, "prepare_rootfs_" + prefix) |
240 | method(rootfs, oe_builddir, rootfs_dir, native_sysroot, pseudo) | 257 | method(rootfs, cr_workdir, oe_builddir, rootfs_dir, native_sysroot, pseudo) |
241 | self.source_file = rootfs | 258 | self.source_file = rootfs |
242 | 259 | ||
243 | # get the rootfs size in the right units for kickstart (kB) | 260 | # get the rootfs size in the right units for kickstart (kB) |
@@ -245,7 +262,7 @@ class Partition(): | |||
245 | out = exec_cmd(du_cmd) | 262 | out = exec_cmd(du_cmd) |
246 | self.size = int(out.split()[0]) | 263 | self.size = int(out.split()[0]) |
247 | 264 | ||
248 | def prepare_rootfs_ext(self, rootfs, oe_builddir, rootfs_dir, | 265 | def prepare_rootfs_ext(self, rootfs, cr_workdir, oe_builddir, rootfs_dir, |
249 | native_sysroot, pseudo): | 266 | native_sysroot, pseudo): |
250 | """ | 267 | """ |
251 | Prepare content for an ext2/3/4 rootfs partition. | 268 | Prepare content for an ext2/3/4 rootfs partition. |
@@ -269,10 +286,21 @@ class Partition(): | |||
269 | (self.fstype, extraopts, rootfs, label_str, self.fsuuid, rootfs_dir) | 286 | (self.fstype, extraopts, rootfs, label_str, self.fsuuid, rootfs_dir) |
270 | exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo) | 287 | exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo) |
271 | 288 | ||
289 | if self.updated_fstab_path and self.has_fstab: | ||
290 | debugfs_script_path = os.path.join(cr_workdir, "debugfs_script") | ||
291 | with open(debugfs_script_path, "w") as f: | ||
292 | f.write("cd etc\n") | ||
293 | f.write("rm fstab\n") | ||
294 | f.write("write %s fstab\n" % (self.updated_fstab_path)) | ||
295 | debugfs_cmd = "debugfs -w -f %s %s" % (debugfs_script_path, rootfs) | ||
296 | exec_native_cmd(debugfs_cmd, native_sysroot) | ||
297 | |||
272 | mkfs_cmd = "fsck.%s -pvfD %s" % (self.fstype, rootfs) | 298 | mkfs_cmd = "fsck.%s -pvfD %s" % (self.fstype, rootfs) |
273 | exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo) | 299 | exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo) |
274 | 300 | ||
275 | def prepare_rootfs_btrfs(self, rootfs, oe_builddir, rootfs_dir, | 301 | self.check_for_Y2038_problem(rootfs, native_sysroot) |
302 | |||
303 | def prepare_rootfs_btrfs(self, rootfs, cr_workdir, oe_builddir, rootfs_dir, | ||
276 | native_sysroot, pseudo): | 304 | native_sysroot, pseudo): |
277 | """ | 305 | """ |
278 | Prepare content for a btrfs rootfs partition. | 306 | Prepare content for a btrfs rootfs partition. |
@@ -295,7 +323,7 @@ class Partition(): | |||
295 | self.mkfs_extraopts, self.fsuuid, rootfs) | 323 | self.mkfs_extraopts, self.fsuuid, rootfs) |
296 | exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo) | 324 | exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo) |
297 | 325 | ||
298 | def prepare_rootfs_msdos(self, rootfs, oe_builddir, rootfs_dir, | 326 | def prepare_rootfs_msdos(self, rootfs, cr_workdir, oe_builddir, rootfs_dir, |
299 | native_sysroot, pseudo): | 327 | native_sysroot, pseudo): |
300 | """ | 328 | """ |
301 | Prepare content for a msdos/vfat rootfs partition. | 329 | Prepare content for a msdos/vfat rootfs partition. |
@@ -324,12 +352,16 @@ class Partition(): | |||
324 | mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (rootfs, rootfs_dir) | 352 | mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (rootfs, rootfs_dir) |
325 | exec_native_cmd(mcopy_cmd, native_sysroot) | 353 | exec_native_cmd(mcopy_cmd, native_sysroot) |
326 | 354 | ||
355 | if self.updated_fstab_path and self.has_fstab: | ||
356 | mcopy_cmd = "mcopy -i %s %s ::/etc/fstab" % (rootfs, self.updated_fstab_path) | ||
357 | exec_native_cmd(mcopy_cmd, native_sysroot) | ||
358 | |||
327 | chmod_cmd = "chmod 644 %s" % rootfs | 359 | chmod_cmd = "chmod 644 %s" % rootfs |
328 | exec_cmd(chmod_cmd) | 360 | exec_cmd(chmod_cmd) |
329 | 361 | ||
330 | prepare_rootfs_vfat = prepare_rootfs_msdos | 362 | prepare_rootfs_vfat = prepare_rootfs_msdos |
331 | 363 | ||
332 | def prepare_rootfs_squashfs(self, rootfs, oe_builddir, rootfs_dir, | 364 | def prepare_rootfs_squashfs(self, rootfs, cr_workdir, oe_builddir, rootfs_dir, |
333 | native_sysroot, pseudo): | 365 | native_sysroot, pseudo): |
334 | """ | 366 | """ |
335 | Prepare content for a squashfs rootfs partition. | 367 | Prepare content for a squashfs rootfs partition. |
@@ -358,6 +390,8 @@ class Partition(): | |||
358 | (self.fstype, extraopts, label_str, self.fsuuid, rootfs) | 390 | (self.fstype, extraopts, label_str, self.fsuuid, rootfs) |
359 | exec_native_cmd(mkfs_cmd, native_sysroot) | 391 | exec_native_cmd(mkfs_cmd, native_sysroot) |
360 | 392 | ||
393 | self.check_for_Y2038_problem(rootfs, native_sysroot) | ||
394 | |||
361 | def prepare_empty_partition_btrfs(self, rootfs, oe_builddir, | 395 | def prepare_empty_partition_btrfs(self, rootfs, oe_builddir, |
362 | native_sysroot): | 396 | native_sysroot): |
363 | """ | 397 | """ |
@@ -419,3 +453,37 @@ class Partition(): | |||
419 | 453 | ||
420 | mkswap_cmd = "mkswap %s -U %s %s" % (label_str, self.fsuuid, path) | 454 | mkswap_cmd = "mkswap %s -U %s %s" % (label_str, self.fsuuid, path) |
421 | exec_native_cmd(mkswap_cmd, native_sysroot) | 455 | exec_native_cmd(mkswap_cmd, native_sysroot) |
456 | |||
457 | def check_for_Y2038_problem(self, rootfs, native_sysroot): | ||
458 | """ | ||
459 | Check if the filesystem is affected by the Y2038 problem | ||
460 | (Y2038 problem = 32 bit time_t overflow in January 2038) | ||
461 | """ | ||
462 | def get_err_str(part): | ||
463 | err = "The {} filesystem {} has no Y2038 support." | ||
464 | if part.mountpoint: | ||
465 | args = [part.fstype, "mounted at %s" % part.mountpoint] | ||
466 | elif part.label: | ||
467 | args = [part.fstype, "labeled '%s'" % part.label] | ||
468 | elif part.part_name: | ||
469 | args = [part.fstype, "in partition '%s'" % part.part_name] | ||
470 | else: | ||
471 | args = [part.fstype, "in partition %s" % part.num] | ||
472 | return err.format(*args) | ||
473 | |||
474 | # ext2 and ext3 are always affected by the Y2038 problem | ||
475 | if self.fstype in ["ext2", "ext3"]: | ||
476 | logger.warn(get_err_str(self)) | ||
477 | return | ||
478 | |||
479 | ret, out = exec_native_cmd("dumpe2fs %s" % rootfs, native_sysroot) | ||
480 | |||
481 | # if ext4 is affected by the Y2038 problem depends on the inode size | ||
482 | for line in out.splitlines(): | ||
483 | if line.startswith("Inode size:"): | ||
484 | size = int(line.split(":")[1].strip()) | ||
485 | if size < 256: | ||
486 | logger.warn("%s Inodes (of size %d) are too small." % | ||
487 | (get_err_str(self), size)) | ||
488 | break | ||
489 | |||