paycheck: truncate partitions resulting from applying a payload
Since the correctness of the result only encompasses the filesystem (or
otherwise "meaningful data") on the target partition, it is desirable to
actually get rid of whatever is past that point. There are different
reasons for the presence of such extra space in delta updates, including
remnants from a source partition that served as baseline for a delta
update, or scratch space used by MOVE operations for breaking cycles.
We make truncation the default behavior, although it can be suppressed
by passing the right flag (truncate_to_expected_size=False). Note that
this change is necessary for comparing the results of applying a payload
to the partitions as they are extracted from a target image, which is to
be attempted during payload generation.
This also fixes tiny gpylint complaints.
BUG=chromium:241283
TEST=Emitted partition files truncated as expected
Change-Id: Ibb71e4f2305ec41224afdc503168ae02c312f6fe
Reviewed-on: https://gerrit.chromium.org/gerrit/56532
Tested-by: Gilad Arnold <garnold@chromium.org>
Commit-Queue: Gilad Arnold <garnold@chromium.org>
Reviewed-by: Gilad Arnold <garnold@chromium.org>
diff --git a/scripts/update_payload/applier.py b/scripts/update_payload/applier.py
index f5ae6b7..52a70f9 100644
--- a/scripts/update_payload/applier.py
+++ b/scripts/update_payload/applier.py
@@ -192,18 +192,23 @@
"""
- def __init__(self, payload, bsdiff_in_place=True):
+ def __init__(self, payload, bsdiff_in_place=True,
+ truncate_to_expected_size=True):
"""Initialize the applier.
Args:
payload: the payload object to check
bsdiff_in_place: whether to perform BSDIFF operation in-place (optional)
+ truncate_to_expected_size: whether to truncate the resulting partitions
+ to their expected sizes, as specified in the
+ payload (optional)
"""
assert payload.is_init, 'uninitialized update payload'
self.payload = payload
self.block_size = payload.manifest.block_size
self.bsdiff_in_place = bsdiff_in_place
+ self.truncate_to_expected_size = truncate_to_expected_size
def _ApplyReplaceOperation(self, op, op_name, out_data, part_file, part_size):
"""Applies a REPLACE{,_BZ} operation.
@@ -430,6 +435,12 @@
with open(new_part_file_name, 'r+b') as new_part_file:
self._ApplyOperations(operations, base_name, new_part_file,
new_part_info.size)
+ # Truncate the result, if so instructed.
+ if self.truncate_to_expected_size:
+ new_part_file.seek(0, 2)
+ if new_part_file.tell() > new_part_info.size:
+ new_part_file.seek(new_part_info.size)
+ new_part_file.truncate()
# Verify the resulting partition.
with open(new_part_file_name, 'rb') as new_part_file:
diff --git a/scripts/update_payload/payload.py b/scripts/update_payload/payload.py
index 1796f51..0bac091 100644
--- a/scripts/update_payload/payload.py
+++ b/scripts/update_payload/payload.py
@@ -155,7 +155,7 @@
self.is_init = True
def Describe(self):
-
+ """Emits the payload embedded description data to standard output."""
def _DescribeImageInfo(description, image_info):
def _DisplayIndentedValue(name, value):
print ' {:<14} {}'.format(name+':', value)
@@ -166,16 +166,18 @@
_DisplayIndentedValue('Version', image_info.version)
_DisplayIndentedValue('Key', image_info.key)
- if (image_info.build_channel != image_info.channel):
+ if image_info.build_channel != image_info.channel:
_DisplayIndentedValue('Build channel', image_info.build_channel)
- if (image_info.build_version != image_info.version):
+ if image_info.build_version != image_info.version:
_DisplayIndentedValue('Build version', image_info.build_version)
if self.manifest.HasField('old_image_info'):
+ # pylint: disable=E1101
_DescribeImageInfo('Old Image', self.manifest.old_image_info)
if self.manifest.HasField('new_image_info'):
+ # pylint: disable=E1101
_DescribeImageInfo('New Image', self.manifest.new_image_info)
def _AssertInit(self):
@@ -230,7 +232,8 @@
report_out_file=report_out_file)
def Apply(self, new_kernel_part, new_rootfs_part, old_kernel_part=None,
- old_rootfs_part=None, bsdiff_in_place=True):
+ old_rootfs_part=None, bsdiff_in_place=True,
+ truncate_to_expected_size=True):
"""Applies the update payload.
Args:
@@ -239,6 +242,9 @@
old_kernel_part: name of source kernel partition file (optional)
old_rootfs_part: name of source rootfs partition file (optional)
bsdiff_in_place: whether to perform BSDIFF operations in-place (optional)
+ truncate_to_expected_size: whether to truncate the resulting partitions
+ to their expected sizes, as specified in the
+ payload (optional)
Raises:
PayloadError if payload application failed.
@@ -246,7 +252,9 @@
self._AssertInit()
# Create a short-lived payload applier object and run it.
- helper = applier.PayloadApplier(self, bsdiff_in_place=bsdiff_in_place)
+ helper = applier.PayloadApplier(
+ self, bsdiff_in_place=bsdiff_in_place,
+ truncate_to_expected_size=truncate_to_expected_size)
helper.Run(new_kernel_part, new_rootfs_part,
old_kernel_part=old_kernel_part,
old_rootfs_part=old_rootfs_part)