diff options
author | Sami Tolvanen <samitolvanen@google.com> | 2016-02-09 12:28:58 -0800 |
---|---|---|
committer | Sami Tolvanen <samitolvanen@google.com> | 2016-02-10 09:37:59 -0800 |
commit | 6a8781a25113b9b49dddc8c8e043c27d5a943e3a (patch) | |
tree | 3a4ca1c229176bd3e257e49b5c3e898731d5f014 | |
parent | 74606c40cdf0552c58b07b1477e79690e6037930 (diff) | |
download | build-6a8781a25113b9b49dddc8c8e043c27d5a943e3a.tar.gz |
Fix metadata location when file system doesn't span the partition
Pad the sparse image with a zero fill chunk to correctly position
verity and FEC metadata at the end of the partition.
Bug: 27073791
Change-Id: I9f70d579a42e5007d50e9c02a98a608d2815f0ed
-rwxr-xr-x | tools/releasetools/build_image.py | 21 | ||||
-rw-r--r-- | tools/releasetools/sparse_img.py | 24 |
2 files changed, 35 insertions, 10 deletions
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py index e6ad18b821..e248860d3d 100755 --- a/tools/releasetools/build_image.py +++ b/tools/releasetools/build_image.py @@ -28,6 +28,7 @@ import sys import commands import common import shutil +import sparse_img import tempfile OPTIONS = common.OPTIONS @@ -91,6 +92,16 @@ def GetVeritySize(partition_size, fec_supported): return verity_size + fec_size return verity_size +def GetSimgSize(image_file): + simg = sparse_img.SparseImage(image_file, build_map=False) + return simg.blocksize * simg.total_blocks + +def ZeroPadSimg(image_file, pad_size): + blocks = pad_size // BLOCK_SIZE + print("Padding %d blocks (%d bytes)" % (blocks, pad_size)) + simg = sparse_img.SparseImage(image_file, mode="r+b", build_map=False) + simg.AppendFillChunk(0, blocks) + def AdjustPartitionSizeForVerity(partition_size, fec_supported): """Modifies the provided partition size to account for the verity metadata. @@ -329,7 +340,7 @@ def BuildImage(in_dir, prop_dict, out_file, target_out=None): # Adjust the partition size to make room for the hashes if this is to be # verified. - if verity_supported and is_verity_partition and fs_spans_partition: + if verity_supported and is_verity_partition: partition_size = int(prop_dict.get("partition_size")) adjusted_size = AdjustPartitionSizeForVerity(partition_size, verity_fec_supported) @@ -440,17 +451,13 @@ def BuildImage(in_dir, prop_dict, out_file, target_out=None): if not fs_spans_partition: mount_point = prop_dict.get("mount_point") partition_size = int(prop_dict.get("partition_size")) - image_size = os.stat(out_file).st_size + image_size = GetSimgSize(out_file) if image_size > partition_size: print("Error: %s image size of %d is larger than partition size of " "%d" % (mount_point, image_size, partition_size)) return False if verity_supported and is_verity_partition: - if 2 * image_size - AdjustPartitionSizeForVerity(image_size, verity_fec_supported) > partition_size: - print "Error: No more room on %s to fit verity data" % mount_point - return False - prop_dict["original_partition_size"] = prop_dict["partition_size"] - prop_dict["partition_size"] = str(image_size) + ZeroPadSimg(out_file, partition_size - image_size) # create the verified image if this is to be verified if verity_supported and is_verity_partition: diff --git a/tools/releasetools/sparse_img.py b/tools/releasetools/sparse_img.py index 013044f6ff..4ba7560dfc 100644 --- a/tools/releasetools/sparse_img.py +++ b/tools/releasetools/sparse_img.py @@ -31,8 +31,9 @@ class SparseImage(object): the form of a string like "0" or "0 1-5 8". """ - def __init__(self, simg_fn, file_map_fn=None, clobbered_blocks=None): - self.simg_f = f = open(simg_fn, "rb") + def __init__(self, simg_fn, file_map_fn=None, clobbered_blocks=None, + mode="rb", build_map=True): + self.simg_f = f = open(simg_fn, mode) header_bin = f.read(28) header = struct.unpack("<I4H4I", header_bin) @@ -44,7 +45,7 @@ class SparseImage(object): chunk_hdr_sz = header[4] self.blocksize = blk_sz = header[5] self.total_blocks = total_blks = header[6] - total_chunks = header[7] + self.total_chunks = total_chunks = header[7] if magic != 0xED26FF3A: raise ValueError("Magic should be 0xED26FF3A but is 0x%08X" % (magic,)) @@ -61,6 +62,9 @@ class SparseImage(object): print("Total of %u %u-byte output blocks in %u input chunks." % (total_blks, blk_sz, total_chunks)) + if not build_map: + return + pos = 0 # in blocks care_data = [] self.offset_map = offset_map = [] @@ -126,6 +130,20 @@ class SparseImage(object): else: self.file_map = {"__DATA": self.care_map} + def AppendFillChunk(self, data, blocks): + f = self.simg_f + + # Append a fill chunk + f.seek(0, os.SEEK_END) + f.write(struct.pack("<2H3I", 0xCAC2, 0, blocks, 16, data)) + + # Update the sparse header + self.total_blocks += blocks + self.total_chunks += 1 + + f.seek(16, os.SEEK_SET) + f.write(struct.pack("<2I", self.total_blocks, self.total_chunks)) + def ReadRangeSet(self, ranges): return [d for d in self._GetRangeData(ranges)] |