aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSami Tolvanen <samitolvanen@google.com>2016-02-09 12:28:58 -0800
committerSami Tolvanen <samitolvanen@google.com>2016-02-10 09:37:59 -0800
commit6a8781a25113b9b49dddc8c8e043c27d5a943e3a (patch)
tree3a4ca1c229176bd3e257e49b5c3e898731d5f014
parent74606c40cdf0552c58b07b1477e79690e6037930 (diff)
downloadbuild-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-xtools/releasetools/build_image.py21
-rw-r--r--tools/releasetools/sparse_img.py24
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)]