diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py index 10aecf921..4af10ca53 100755 --- a/tools/releasetools/add_img_to_target_files.py +++ b/tools/releasetools/add_img_to_target_files.py @@ -113,22 +113,33 @@ def GetCareMap(which, imgname): Returns: (which, care_map_ranges): care_map_ranges is the raw string of the care_map - RangeSet. + RangeSet; or an empty list. """ assert which in common.PARTITIONS_WITH_CARE_MAP - simg = sparse_img.SparseImage(imgname) - care_map_ranges = simg.care_map - size_key = which + "_image_size" - image_size = OPTIONS.info_dict.get(size_key) - if image_size: - # excludes the verity metadata blocks of the given image. When AVB is enabled, - # this size is the max image size returned by the AVB tool - image_blocks = int(image_size) / 4096 - 1 - assert image_blocks > 0, "blocks for {} must be positive".format(which) - care_map_ranges = care_map_ranges.intersect( + # which + "_image_size" contains the size that the actual filesystem image + # resides in, which is all that needs to be verified. The additional blocks in + # the image file contain verity metadata, by reading which would trigger + # invalid reads. + image_size = OPTIONS.info_dict.get(which + "_image_size") + if not image_size: + return [] + + image_blocks = int(image_size) / 4096 - 1 + assert image_blocks > 0, "blocks for {} must be positive".format(which) + + # For sparse images, we will only check the blocks that are listed in the care + # map, i.e. the ones with meaningful data. + if "extfs_sparse_flag" in OPTIONS.info_dict: + simg = sparse_img.SparseImage(imgname) + care_map_ranges = simg.care_map.intersect( rangelib.RangeSet("0-{}".format(image_blocks))) + # Otherwise for non-sparse images, we read all the blocks in the filesystem + # image. + else: + care_map_ranges = rangelib.RangeSet("0-{}".format(image_blocks)) + return [which, care_map_ranges.to_string_raw()] diff --git a/tools/releasetools/test_add_img_to_target_files.py b/tools/releasetools/test_add_img_to_target_files.py index 013ade65b..422262cde 100644 --- a/tools/releasetools/test_add_img_to_target_files.py +++ b/tools/releasetools/test_add_img_to_target_files.py @@ -123,6 +123,9 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): def _test_AddCareMapForAbOta(): """Helper function to set up the test for test_AddCareMapForAbOta().""" OPTIONS.info_dict = { + 'extfs_sparse_flag' : '-s', + 'system_image_size' : 65536, + 'vendor_image_size' : 40960, 'system_verity_block_device': '/dev/block/system', 'vendor_verity_block_device': '/dev/block/vendor', 'system.build.prop': { @@ -131,7 +134,7 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): }, 'vendor.build.prop': { 'ro.vendor.build.fingerprint': 'google/sailfish/678:user/dev-keys', - } + }, } # Prepare the META/ folder. @@ -142,9 +145,9 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): system_image = test_utils.construct_sparse_image([ (0xCAC1, 6), (0xCAC3, 4), - (0xCAC1, 6)]) + (0xCAC1, 8)]) vendor_image = test_utils.construct_sparse_image([ - (0xCAC2, 10)]) + (0xCAC2, 12)]) image_paths = { 'system' : system_image, @@ -203,6 +206,9 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): """Tests the case for device using AVB.""" image_paths = self._test_AddCareMapForAbOta() OPTIONS.info_dict = { + 'extfs_sparse_flag' : '-s', + 'system_image_size' : 65536, + 'vendor_image_size' : 40960, 'avb_system_hashtree_enable' : 'true', 'avb_vendor_hashtree_enable' : 'true', 'system.build.prop': { @@ -231,6 +237,9 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): """Tests the case for partitions without fingerprint.""" image_paths = self._test_AddCareMapForAbOta() OPTIONS.info_dict = { + 'extfs_sparse_flag' : '-s', + 'system_image_size' : 65536, + 'vendor_image_size' : 40960, 'system_verity_block_device': '/dev/block/system', 'vendor_verity_block_device': '/dev/block/vendor', } @@ -249,6 +258,9 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): """Tests the case for partitions with thumbprint.""" image_paths = self._test_AddCareMapForAbOta() OPTIONS.info_dict = { + 'extfs_sparse_flag' : '-s', + 'system_image_size' : 65536, + 'vendor_image_size' : 40960, 'system_verity_block_device': '/dev/block/system', 'vendor_verity_block_device': '/dev/block/vendor', 'system.build.prop': { @@ -256,7 +268,7 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): }, 'vendor.build.prop' : { 'ro.vendor.build.thumbprint': 'google/sailfish/456:user/dev-keys', - } + }, } AddCareMapForAbOta(None, ['system', 'vendor'], image_paths) @@ -370,6 +382,7 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): (0xCAC3, 4), (0xCAC1, 6)]) OPTIONS.info_dict = { + 'extfs_sparse_flag' : '-s', 'system_image_size' : 53248, } name, care_map = GetCareMap('system', sparse_image) @@ -385,6 +398,17 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): (0xCAC3, 4), (0xCAC1, 6)]) OPTIONS.info_dict = { + 'extfs_sparse_flag' : '-s', 'system_image_size' : -45056, } self.assertRaises(AssertionError, GetCareMap, 'system', sparse_image) + + def test_GetCareMap_nonSparseImage(self): + OPTIONS.info_dict = { + 'system_image_size' : 53248, + } + # 'foo' is the image filename, which is expected to be not used by + # GetCareMap(). + name, care_map = GetCareMap('system', 'foo') + self.assertEqual('system', name) + self.assertEqual(RangeSet("0-12").to_string_raw(), care_map)