Merge "Moving recovery resources from /system to /vendor"

am: 959b5ebbf8

Change-Id: Ied05e3765ea8afbc29b4d9bf713217d0d3753fa5
This commit is contained in:
Bill Peckham 2019-10-04 20:24:19 -07:00 committed by android-build-merger
commit 2c4d3a7b6c
9 changed files with 111 additions and 69 deletions

View file

@ -1924,7 +1924,8 @@ endif
ifeq (,$(filter true, $(BOARD_USES_FULL_RECOVERY_IMAGE) $(BOARD_USES_RECOVERY_AS_BOOT) \
$(BOARD_BUILD_SYSTEM_ROOT_IMAGE) $(BOARD_INCLUDE_RECOVERY_DTBO) $(BOARD_INCLUDE_RECOVERY_ACPIO)))
# Named '.dat' so we don't attempt to use imgdiff for patching it.
RECOVERY_RESOURCE_ZIP := $(TARGET_OUT)/etc/recovery-resource.dat
RECOVERY_RESOURCE_ZIP := $(TARGET_OUT_VENDOR)/etc/recovery-resource.dat
ALL_DEFAULT_INSTALLED_MODULES += $(RECOVERY_RESOURCE_ZIP)
else
RECOVERY_RESOURCE_ZIP :=
endif
@ -2294,8 +2295,7 @@ PDK_FUSION_SYSIMG_FILES := \
INTERNAL_SYSTEMIMAGE_FILES := $(sort $(filter $(TARGET_OUT)/%, \
$(ALL_GENERATED_SOURCES) \
$(ALL_DEFAULT_INSTALLED_MODULES) \
$(PDK_FUSION_SYSIMG_FILES) \
$(RECOVERY_RESOURCE_ZIP)) \
$(PDK_FUSION_SYSIMG_FILES)) \
$(PDK_FUSION_SYMLINK_STAMP))
FULL_SYSTEMIMAGE_DEPS := $(INTERNAL_SYSTEMIMAGE_FILES) $(INTERNAL_USERIMAGES_DEPS)
@ -3893,6 +3893,9 @@ endif
ifeq ($(BOARD_USES_FULL_RECOVERY_IMAGE),true)
$(hide) echo "full_recovery_image=true" >> $@
endif
ifdef BOARD_USES_VENDORIMAGE
$(hide) echo "board_uses_vendorimage=true" >> $@
endif
ifeq ($(BOARD_AVB_ENABLE),true)
$(hide) echo "avb_enable=true" >> $@
$(hide) echo "avb_vbmeta_key_path=$(BOARD_AVB_KEY_PATH)" >> $@
@ -4299,10 +4302,8 @@ ifneq ($(PRODUCT_ODM_BASE_FS_PATH),)
$(zip_root)/META/$(notdir $(PRODUCT_ODM_BASE_FS_PATH))
endif
ifneq ($(INSTALLED_RECOVERYIMAGE_TARGET),)
ifdef BUILDING_SYSTEM_IMAGE
$(hide) PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH MKBOOTIMG=$(MKBOOTIMG) \
$(MAKE_RECOVERY_PATCH) $(zip_root) $(zip_root)
endif # BUILDING_SYSTEM_IMAGE
endif
ifeq ($(AB_OTA_UPDATER),true)
@# When using the A/B updater, include the updater config files in the zip.

View file

@ -29,7 +29,6 @@ PRODUCT_PACKAGES += \
android.test.mock \
android.test.runner \
apexd \
applypatch \
appops \
app_process \
appwidget \

View file

@ -75,3 +75,8 @@ PRODUCT_PACKAGES += \
# VINTF data for vendor image
PRODUCT_PACKAGES += \
device_compatibility_matrix.xml \
# Packages to update the recovery partition, which will be installed on
# /vendor. TODO(b/141648565): Don't install these unless they're needed.
PRODUCT_PACKAGES += \
applypatch

View file

@ -165,9 +165,12 @@ def AddSystem(output_zip, recovery_img=None, boot_img=None):
else:
common.ZipWrite(output_zip, output_file, arc_name)
if (OPTIONS.rebuild_recovery and recovery_img is not None and
boot_img is not None):
logger.info("Building new recovery patch")
board_uses_vendorimage = OPTIONS.info_dict.get(
"board_uses_vendorimage") == "true"
if (OPTIONS.rebuild_recovery and not board_uses_vendorimage and
recovery_img is not None and boot_img is not None):
logger.info("Building new recovery patch on system at system/vendor")
common.MakeRecoveryPatch(OPTIONS.input_tmp, output_sink, recovery_img,
boot_img, info_dict=OPTIONS.info_dict)
@ -190,7 +193,7 @@ def AddSystemOther(output_zip):
CreateImage(OPTIONS.input_tmp, OPTIONS.info_dict, "system_other", img)
def AddVendor(output_zip):
def AddVendor(output_zip, recovery_img=None, boot_img=None):
"""Turn the contents of VENDOR into a vendor image and store in it
output_zip."""
@ -199,6 +202,27 @@ def AddVendor(output_zip):
logger.info("vendor.img already exists; no need to rebuild...")
return img.name
def output_sink(fn, data):
ofile = open(os.path.join(OPTIONS.input_tmp, "VENDOR", fn), "w")
ofile.write(data)
ofile.close()
if output_zip:
arc_name = "VENDOR/" + fn
if arc_name in output_zip.namelist():
OPTIONS.replace_updated_files_list.append(arc_name)
else:
common.ZipWrite(output_zip, ofile.name, arc_name)
board_uses_vendorimage = OPTIONS.info_dict.get(
"board_uses_vendorimage") == "true"
if (OPTIONS.rebuild_recovery and board_uses_vendorimage and
recovery_img is not None and boot_img is not None):
logger.info("Building new recovery patch on vendor")
common.MakeRecoveryPatch(OPTIONS.input_tmp, output_sink, recovery_img,
boot_img, info_dict=OPTIONS.info_dict)
block_list = OutputFile(output_zip, OPTIONS.input_tmp, "IMAGES", "vendor.map")
CreateImage(OPTIONS.input_tmp, OPTIONS.info_dict, "vendor", img,
block_list=block_list)
@ -781,7 +805,8 @@ def AddImagesToTargetFiles(filename):
if has_vendor:
banner("vendor")
partitions['vendor'] = AddVendor(output_zip)
partitions['vendor'] = AddVendor(
output_zip, recovery_img=recovery_image, boot_img=boot_image)
if has_product:
banner("product")

View file

@ -2535,13 +2535,25 @@ def MakeRecoveryPatch(input_dir, output_sink, recovery_img, boot_img,
info_dict = OPTIONS.info_dict
full_recovery_image = info_dict.get("full_recovery_image") == "true"
board_uses_vendorimage = info_dict.get("board_uses_vendorimage") == "true"
if board_uses_vendorimage:
# In this case, the output sink is rooted at VENDOR
recovery_img_path = "etc/recovery.img"
recovery_resource_dat_path = "VENDOR/etc/recovery-resource.dat"
sh_dir = "bin"
else:
# In this case the output sink is rooted at SYSTEM
recovery_img_path = "vendor/etc/recovery.img"
recovery_resource_dat_path = "SYSTEM/vendor/etc/recovery-resource.dat"
sh_dir = "vendor/bin"
if full_recovery_image:
output_sink("etc/recovery.img", recovery_img.data)
output_sink(recovery_img_path, recovery_img.data)
else:
system_root_image = info_dict.get("system_root_image") == "true"
path = os.path.join(input_dir, "SYSTEM", "etc", "recovery-resource.dat")
path = os.path.join(input_dir, recovery_resource_dat_path)
# With system-root-image, boot and recovery images will have mismatching
# entries (only recovery has the ramdisk entry) (Bug: 72731506). Use bsdiff
# to handle such a case.
@ -2554,7 +2566,7 @@ def MakeRecoveryPatch(input_dir, output_sink, recovery_img, boot_img,
if os.path.exists(path):
diff_program.append("-b")
diff_program.append(path)
bonus_args = "--bonus /system/etc/recovery-resource.dat"
bonus_args = "--bonus /vendor/etc/recovery-resource.dat"
else:
bonus_args = ""
@ -2571,10 +2583,16 @@ def MakeRecoveryPatch(input_dir, output_sink, recovery_img, boot_img,
return
if full_recovery_image:
sh = """#!/system/bin/sh
# Note that we use /vendor to refer to the recovery resources. This will
# work for a separate vendor partition mounted at /vendor or a
# /system/vendor subdirectory on the system partition, for which init will
# create a symlink from /vendor to /system/vendor.
sh = """#!/vendor/bin/sh
if ! applypatch --check %(type)s:%(device)s:%(size)d:%(sha1)s; then
applypatch \\
--flash /system/etc/recovery.img \\
--flash /vendor/etc/recovery.img \\
--target %(type)s:%(device)s:%(size)d:%(sha1)s && \\
log -t recovery "Installing new recovery image: succeeded" || \\
log -t recovery "Installing new recovery image: failed"
@ -2586,10 +2604,10 @@ fi
'sha1': recovery_img.sha1,
'size': recovery_img.size}
else:
sh = """#!/system/bin/sh
sh = """#!/vendor/bin/sh
if ! applypatch --check %(recovery_type)s:%(recovery_device)s:%(recovery_size)d:%(recovery_sha1)s; then
applypatch %(bonus_args)s \\
--patch /system/recovery-from-boot.p \\
--patch /vendor/recovery-from-boot.p \\
--source %(boot_type)s:%(boot_device)s:%(boot_size)d:%(boot_sha1)s \\
--target %(recovery_type)s:%(recovery_device)s:%(recovery_size)d:%(recovery_sha1)s && \\
log -t recovery "Installing new recovery image: succeeded" || \\
@ -2607,9 +2625,9 @@ fi
'recovery_device': recovery_device,
'bonus_args': bonus_args}
# The install script location moved from /system/etc to /system/bin
# in the L release.
sh_location = "bin/install-recovery.sh"
# The install script location moved from /system/etc to /system/bin in the L
# release. In the R release it is in VENDOR/bin or SYSTEM/vendor/bin.
sh_location = os.path.join(sh_dir, "install-recovery.sh")
logger.info("putting script in %s", sh_location)

View file

@ -47,8 +47,17 @@ def main(argv):
if not recovery_img or not boot_img:
sys.exit(0)
board_uses_vendorimage = OPTIONS.info_dict.get(
"board_uses_vendorimage") == "true"
if board_uses_vendorimage:
target_files_dir = "VENDOR"
else:
target_files_dir = "SYSTEM"
def output_sink(fn, data):
with open(os.path.join(output_dir, "SYSTEM", *fn.split("/")), "wb") as f:
with open(os.path.join(output_dir, target_files_dir,
*fn.split("/")), "wb") as f:
f.write(data)
common.MakeRecoveryPatch(input_dir, output_sink, recovery_img, boot_img)

View file

@ -68,8 +68,7 @@ Usage: merge_target_files.py [args]
files package and saves it at this path.
--rebuild_recovery
Rebuild the recovery patch used by non-A/B devices and write it to the
system image.
Deprecated; does nothing.
--keep-tmp
Keep tempoary files for debugging purposes.
@ -106,6 +105,7 @@ OPTIONS.output_item_list = None
OPTIONS.output_ota = None
OPTIONS.output_img = None
OPTIONS.output_super_empty = None
# TODO(b/132730255): Remove this option.
OPTIONS.rebuild_recovery = False
OPTIONS.keep_tmp = False
@ -372,32 +372,6 @@ def process_ab_partitions_txt(framework_target_files_temp_dir,
write_sorted_data(data=output_ab_partitions, path=output_ab_partitions_txt)
def append_recovery_to_filesystem_config(output_target_files_temp_dir):
"""Performs special processing for META/filesystem_config.txt.
This function appends recovery information to META/filesystem_config.txt so
that recovery patch regeneration will succeed.
Args:
output_target_files_temp_dir: The name of a directory that will be used to
create the output target files package after all the special cases are
processed. We find filesystem_config.txt here.
"""
filesystem_config_txt = os.path.join(output_target_files_temp_dir, 'META',
'filesystem_config.txt')
with open(filesystem_config_txt, 'a') as f:
# TODO(bpeckham) this data is hard coded. It should be generated
# programmatically.
f.write('system/bin/install-recovery.sh 0 0 750 '
'selabel=u:object_r:install_recovery_exec:s0 capabilities=0x0\n')
f.write('system/recovery-from-boot.p 0 0 644 '
'selabel=u:object_r:system_file:s0 capabilities=0x0\n')
f.write('system/etc/recovery.img 0 0 440 '
'selabel=u:object_r:install_recovery_exec:s0 capabilities=0x0\n')
def process_misc_info_txt(framework_target_files_temp_dir,
vendor_target_files_temp_dir,
output_target_files_temp_dir,
@ -594,7 +568,7 @@ def copy_file_contexts(framework_target_files_dir, vendor_target_files_dir,
def process_special_cases(framework_target_files_temp_dir,
vendor_target_files_temp_dir,
output_target_files_temp_dir,
framework_misc_info_keys, rebuild_recovery):
framework_misc_info_keys):
"""Performs special-case processing for certain target files items.
Certain files in the output target files package require special-case
@ -611,8 +585,6 @@ def process_special_cases(framework_target_files_temp_dir,
framework_misc_info_keys: A list of keys to obtain from the framework
instance of META/misc_info.txt. The remaining keys from the vendor
instance.
rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
devices and write it to the system image.
"""
if 'ab_update' in framework_misc_info_keys:
@ -621,10 +593,6 @@ def process_special_cases(framework_target_files_temp_dir,
vendor_target_files_temp_dir=vendor_target_files_temp_dir,
output_target_files_temp_dir=output_target_files_temp_dir)
if rebuild_recovery:
append_recovery_to_filesystem_config(
output_target_files_temp_dir=output_target_files_temp_dir)
copy_file_contexts(
framework_target_files_dir=framework_target_files_temp_dir,
vendor_target_files_dir=vendor_target_files_temp_dir,
@ -757,8 +725,7 @@ def create_merged_package(temp_dir, framework_target_files, framework_item_list,
framework_target_files_temp_dir=framework_target_files_temp_dir,
vendor_target_files_temp_dir=vendor_target_files_temp_dir,
output_target_files_temp_dir=output_target_files_temp_dir,
framework_misc_info_keys=framework_misc_info_keys,
rebuild_recovery=rebuild_recovery)
framework_misc_info_keys=framework_misc_info_keys)
return output_target_files_temp_dir
@ -779,6 +746,7 @@ def generate_images(target_files_dir, rebuild_recovery):
add_img_args = ['--verbose']
add_img_args.append('--add_missing')
# TODO(b/132730255): Remove this if statement.
if rebuild_recovery:
add_img_args.append('--rebuild_recovery')
add_img_args.append(target_files_dir)
@ -1016,7 +984,7 @@ def main():
OPTIONS.output_img = a
elif o == '--output-super-empty':
OPTIONS.output_super_empty = a
elif o == '--rebuild_recovery':
elif o == '--rebuild_recovery': # TODO(b/132730255): Warn
OPTIONS.rebuild_recovery = True
elif o == '--keep-tmp':
OPTIONS.keep_tmp = True

View file

@ -731,10 +731,19 @@ def _WriteRecoveryImageToBoot(script, output_zip):
script.WriteRawImage("/boot", "recovery.img")
def HasRecoveryPatch(target_files_zip):
def HasRecoveryPatch(target_files_zip, info_dict):
board_uses_vendorimage = info_dict.get("board_uses_vendorimage") == "true"
if board_uses_vendorimage:
target_files_dir = "VENDOR"
else:
target_files_dir = "SYSTEM/vendor"
patch = "%s/recovery-from-boot.p" % target_files_dir
img = "%s/etc/recovery.img" %target_files_dir
namelist = [name for name in target_files_zip.namelist()]
return ("SYSTEM/recovery-from-boot.p" in namelist or
"SYSTEM/etc/recovery.img" in namelist)
return (patch in namelist or img in namelist)
def HasPartition(target_files_zip, partition):
@ -925,7 +934,7 @@ def WriteFullOTAPackage(input_zip, output_file):
metadata=metadata,
info_dict=OPTIONS.info_dict)
assert HasRecoveryPatch(input_zip)
assert HasRecoveryPatch(input_zip, info_dict=OPTIONS.info_dict)
# Assertions (e.g. downgrade check, device properties check).
ts = target_info.GetBuildProp("ro.build.date.utc")

View file

@ -138,7 +138,7 @@ def ValidateInstallRecoveryScript(input_tmp, info_dict):
1. full recovery:
...
if ! applypatch --check type:device:size:sha1; then
applypatch --flash /system/etc/recovery.img \\
applypatch --flash /vendor/etc/recovery.img \\
type:device:size:sha1 && \\
...
@ -146,18 +146,26 @@ def ValidateInstallRecoveryScript(input_tmp, info_dict):
...
if ! applypatch --check type:recovery_device:recovery_size:recovery_sha1; then
applypatch [--bonus bonus_args] \\
--patch /system/recovery-from-boot.p \\
--patch /vendor/recovery-from-boot.p \\
--source type:boot_device:boot_size:boot_sha1 \\
--target type:recovery_device:recovery_size:recovery_sha1 && \\
...
For full recovery, we want to calculate the SHA-1 of /system/etc/recovery.img
For full recovery, we want to calculate the SHA-1 of /vendor/etc/recovery.img
and compare it against the one embedded in the script. While for recovery
from boot, we want to check the SHA-1 for both recovery.img and boot.img
under IMAGES/.
"""
script_path = 'SYSTEM/bin/install-recovery.sh'
board_uses_vendorimage = info_dict.get("board_uses_vendorimage") == "true"
if board_uses_vendorimage:
script_path = 'VENDOR/bin/install-recovery.sh'
recovery_img = 'VENDOR/etc/recovery.img'
else:
script_path = 'SYSTEM/vendor/bin/install-recovery.sh'
recovery_img = 'SYSTEM/vendor/etc/recovery.img'
if not os.path.exists(os.path.join(input_tmp, script_path)):
logging.info('%s does not exist in input_tmp', script_path)
return
@ -188,7 +196,7 @@ def ValidateInstallRecoveryScript(input_tmp, info_dict):
# Validate the SHA-1 of the recovery image.
recovery_sha1 = flash_partition.split(':')[3]
ValidateFileAgainstSha1(
input_tmp, 'recovery.img', 'SYSTEM/etc/recovery.img', recovery_sha1)
input_tmp, 'recovery.img', recovery_img, recovery_sha1)
else:
assert len(lines) == 11, "Invalid line count: {}".format(lines)