From cfa86223d62a6afa0eb8f5a1a215e985bb0a8c89 Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Mon, 7 Mar 2016 16:31:19 -0800 Subject: [PATCH] Add care_map to target_files package Generate a new file containing care_data of system (and vendor) partition, and add it under META/ of target file package. For A/B update, copy this file to OTA package for later use by update_verifier. Bug: 27175949 Change-Id: I90bb972703afaeb94bc3efe718fd81b1cfbcabcc --- tools/releasetools/add_img_to_target_files.py | 47 ++++++++++++++++--- tools/releasetools/common.py | 22 ++++++--- tools/releasetools/ota_from_target_files.py | 13 +++++ 3 files changed, 69 insertions(+), 13 deletions(-) diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py index ddc0d0b29b..6acc69dbde 100755 --- a/tools/releasetools/add_img_to_target_files.py +++ b/tools/releasetools/add_img_to_target_files.py @@ -37,6 +37,7 @@ import zipfile import build_image import common +import sparse_img OPTIONS = common.OPTIONS @@ -46,6 +47,19 @@ OPTIONS.replace_verity_public_key = False OPTIONS.replace_verity_private_key = False OPTIONS.verity_signer_path = None +def GetCareMap(which, imgname): + """Generate care_map of system (or vendor) partition""" + + assert which in ("system", "vendor") + _, blk_device = common.GetTypeAndDevice("/" + which, OPTIONS.info_dict) + + simg = sparse_img.SparseImage(imgname) + care_map_list = [] + care_map_list.append(blk_device) + care_map_list.append(simg.care_map.to_string_raw()) + return care_map_list + + def AddSystem(output_zip, prefix="IMAGES/", recovery_img=None, boot_img=None): """Turn the contents of SYSTEM into a system image and store it in output_zip.""" @@ -53,7 +67,7 @@ def AddSystem(output_zip, prefix="IMAGES/", recovery_img=None, boot_img=None): prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "system.img") if os.path.exists(prebuilt_path): print "system.img already exists in %s, no need to rebuild..." % (prefix,) - return + return prebuilt_path def output_sink(fn, data): ofile = open(os.path.join(OPTIONS.input_tmp, "SYSTEM", fn), "w") @@ -70,6 +84,7 @@ def AddSystem(output_zip, prefix="IMAGES/", recovery_img=None, boot_img=None): block_list=block_list) common.ZipWrite(output_zip, imgname, prefix + "system.img") common.ZipWrite(output_zip, block_list, prefix + "system.map") + return imgname def BuildSystem(input_dir, info_dict, block_list=None): @@ -103,13 +118,14 @@ def AddVendor(output_zip, prefix="IMAGES/"): prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "vendor.img") if os.path.exists(prebuilt_path): print "vendor.img already exists in %s, no need to rebuild..." % (prefix,) - return + return prebuilt_path block_list = common.MakeTempFile(prefix="vendor-blocklist-", suffix=".map") imgname = BuildVendor(OPTIONS.input_tmp, OPTIONS.info_dict, block_list=block_list) common.ZipWrite(output_zip, imgname, prefix + "vendor.img") common.ZipWrite(output_zip, block_list, prefix + "vendor.map") + return imgname def BuildVendor(input_dir, info_dict, block_list=None): @@ -139,8 +155,9 @@ def CreateImage(input_dir, info_dict, what, block_list=None): image_props = build_image.ImagePropFromGlobalDict(info_dict, what) fstab = info_dict["fstab"] - if fstab: - image_props["fs_type"] = fstab["/" + what].fs_type + mount_point = "/" + what + if fstab and mount_point in fstab: + image_props["fs_type"] = fstab[mount_point].fs_type # Use a fixed timestamp (01/01/2009) when packaging the image. # Bug: 24377993 @@ -330,10 +347,12 @@ def AddImagesToTargetFiles(filename): recovery_image.AddToZip(output_zip) banner("system") - AddSystem(output_zip, recovery_img=recovery_image, boot_img=boot_image) + system_imgname = AddSystem(output_zip, recovery_img=recovery_image, + boot_img=boot_image) + vendor_imgname = None if has_vendor: banner("vendor") - AddVendor(output_zip) + vendor_imgname = AddVendor(output_zip) if has_system_other: banner("system_other") AddSystemOther(output_zip) @@ -348,7 +367,19 @@ def AddImagesToTargetFiles(filename): if os.path.exists(ab_partitions): with open(ab_partitions, 'r') as f: lines = f.readlines() + # For devices using A/B update, generate care_map for system and vendor + # partitions (if present), then write this file to target_files package. + care_map_list = [] for line in lines: + if line.strip() == "system" and OPTIONS.info_dict.get( + "system_verity_block_device", None) is not None: + assert os.path.exists(system_imgname) + care_map_list += GetCareMap("system", system_imgname) + if line.strip() == "vendor" and OPTIONS.info_dict.get( + "vendor_verity_block_device", None) is not None: + assert os.path.exists(vendor_imgname) + care_map_list += GetCareMap("vendor", vendor_imgname) + img_name = line.strip() + ".img" img_radio_path = os.path.join(OPTIONS.input_tmp, "RADIO", img_name) if os.path.exists(img_radio_path): @@ -359,6 +390,10 @@ def AddImagesToTargetFiles(filename): img_path = 'IMAGES/' + img_name assert img_path in output_zip.namelist(), "cannot find " + img_name + if care_map_list: + file_path = "META/care_map.txt" + common.ZipWriteStr(output_zip, file_path, '\n'.join(care_map_list)) + common.ZipClose(output_zip) def main(argv): diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py index 422ba43215..d7f8b16d3c 100644 --- a/tools/releasetools/common.py +++ b/tools/releasetools/common.py @@ -259,11 +259,18 @@ def LoadInfoDict(input_file, input_dir=None): makeint("boot_size") makeint("fstab_version") - if d.get("no_recovery", False) == "true": - d["fstab"] = None - else: + system_root_image = d.get("system_root_image", None) == "true" + if d.get("no_recovery", None) != "true": + recovery_fstab_path = "RECOVERY/RAMDISK/etc/recovery.fstab" d["fstab"] = LoadRecoveryFSTab(read_helper, d["fstab_version"], - d.get("system_root_image", False)) + recovery_fstab_path, system_root_image) + elif d.get("recovery_as_boot", None) == "true": + recovery_fstab_path = "BOOT/RAMDISK/etc/recovery.fstab" + d["fstab"] = LoadRecoveryFSTab(read_helper, d["fstab_version"], + recovery_fstab_path, system_root_image) + else: + d["fstab"] = None + d["build.prop"] = LoadBuildProp(read_helper) return d @@ -286,7 +293,8 @@ def LoadDictionaryFromLines(lines): d[name] = value return d -def LoadRecoveryFSTab(read_helper, fstab_version, system_root_image=False): +def LoadRecoveryFSTab(read_helper, fstab_version, recovery_fstab_path, + system_root_image=False): class Partition(object): def __init__(self, mount_point, fs_type, device, length, device2, context): self.mount_point = mount_point @@ -297,9 +305,9 @@ def LoadRecoveryFSTab(read_helper, fstab_version, system_root_image=False): self.context = context try: - data = read_helper("RECOVERY/RAMDISK/etc/recovery.fstab") + data = read_helper(recovery_fstab_path) except KeyError: - print "Warning: could not find RECOVERY/RAMDISK/etc/recovery.fstab" + print "Warning: could not find {}".format(recovery_fstab_path) data = "" if fstab_version == 1: diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py index b29ba695b6..d3d4974ff7 100755 --- a/tools/releasetools/ota_from_target_files.py +++ b/tools/releasetools/ota_from_target_files.py @@ -1314,6 +1314,19 @@ def WriteABOTAPackageWithBrilloScript(target_file, output_file, compress_type=zipfile.ZIP_STORED) WriteMetadata(metadata, output_zip) + # If dm-verity is supported for the device, copy contents of care_map + # into A/B OTA package. + if OPTIONS.info_dict.get("verity") == "true": + target_zip = zipfile.ZipFile(target_file, "r") + care_map_path = "META/care_map.txt" + namelist = target_zip.namelist() + if care_map_path in namelist: + care_map_data = target_zip.read(care_map_path) + common.ZipWriteStr(output_zip, "care_map.txt", care_map_data) + else: + print "Warning: cannot find care map file in target_file package" + common.ZipClose(target_zip) + # Sign the whole package to comply with the Android OTA package format. common.ZipClose(output_zip) SignOutput(temp_zip_file.name, output_file)