am 57c9ffef: am 9b23f2cd: add option to generate two-step recovery files

* commit '57c9ffef30a6f34e126d8e89a08d208b05cc4901':
  add option to generate two-step recovery files
This commit is contained in:
Doug Zongker 2013-12-03 08:58:11 -08:00 committed by Android Git Automerger
commit a6fadb61ca
2 changed files with 144 additions and 21 deletions

View file

@ -1263,6 +1263,7 @@ ifdef PRODUCT_EXTRA_RECOVERY_KEYS
endif
$(hide) echo 'mkbootimg_args=$(BOARD_MKBOOTIMG_ARGS)' >> $(zip_root)/META/misc_info.txt
$(hide) echo "use_set_metadata=1" >> $(zip_root)/META/misc_info.txt
$(hide) echo "multistage_support=1" >> $(zip_root)/META/misc_info.txt
$(call generate-userimage-prop-dictionary, $(zip_root)/META/misc_info.txt)
@# Zip everything up, preserving symlinks
$(hide) (cd $(zip_root) && zip -qry ../$(notdir $@) .)

View file

@ -52,6 +52,11 @@ Usage: ota_from_target_files [flags] input_target_files output_ota_package
-a (--aslr_mode) <on|off>
Specify whether to turn on ASLR for the package (on by default).
-2 (--two_step)
Generate a 'two-step' OTA package, where recovery is updated
first, so that any changes made to the system partition are done
using the new recovery (new kernel, etc.).
"""
import sys
@ -88,6 +93,7 @@ OPTIONS.omit_prereq = False
OPTIONS.extra_script = None
OPTIONS.aslr_mode = True
OPTIONS.worker_threads = 3
OPTIONS.two_step = False
def MostPopularKey(d, default):
"""Given a dict, return the key corresponding to the largest
@ -404,6 +410,46 @@ def WriteFullOTAPackage(input_zip, output_zip):
AppendAssertions(script, OPTIONS.info_dict)
device_specific.FullOTA_Assertions()
# Two-step package strategy (in chronological order, which is *not*
# the order in which the generated script has things):
#
# if stage is not "2/3" or "3/3":
# write recovery image to boot partition
# set stage to "2/3"
# reboot to boot partition and restart recovery
# else if stage is "2/3":
# write recovery image to recovery partition
# set stage to "3/3"
# reboot to recovery partition and restart recovery
# else:
# (stage must be "3/3")
# set stage to ""
# do normal full package installation:
# wipe and install system, boot image, etc.
# set up system to update recovery partition on first boot
# complete script normally (allow recovery to mark itself finished and reboot)
recovery_img = common.GetBootableImage("recovery.img", "recovery.img",
OPTIONS.input_tmp, "RECOVERY")
if OPTIONS.two_step:
if not OPTIONS.info_dict.get("multistage_support", None):
assert False, "two-step packages not supported by this build"
fs = OPTIONS.info_dict["fstab"]["/misc"]
assert fs.fs_type.upper() == "EMMC", \
"two-step packages only supported on devices with EMMC /misc partitions"
bcb_dev = {"bcb_dev": fs.device}
common.ZipWriteStr(output_zip, "recovery.img", recovery_img.data)
script.AppendExtra("""
if get_stage("%(bcb_dev)s", "stage") == "2/3" then
""" % bcb_dev)
script.WriteRawImage("/recovery", "recovery.img")
script.AppendExtra("""
set_stage("%(bcb_dev)s", "3/3");
reboot_now("%(bcb_dev)s", "recovery");
else if get_stage("%(bcb_dev)s", "stage") == "3/3" then
""" % bcb_dev)
device_specific.FullOTA_InstallBegin()
script.ShowProgress(0.5, 0)
@ -424,8 +470,6 @@ def WriteFullOTAPackage(input_zip, output_zip):
boot_img = common.GetBootableImage("boot.img", "boot.img",
OPTIONS.input_tmp, "BOOT")
recovery_img = common.GetBootableImage("recovery.img", "recovery.img",
OPTIONS.input_tmp, "RECOVERY")
MakeRecoveryPatch(OPTIONS.input_tmp, output_zip, recovery_img, boot_img)
Item.GetMetadata(input_zip)
@ -445,6 +489,19 @@ def WriteFullOTAPackage(input_zip, output_zip):
script.AppendExtra(OPTIONS.extra_script)
script.UnmountAll()
if OPTIONS.two_step:
script.AppendExtra("""
set_stage("%(bcb_dev)s", "");
""" % bcb_dev)
script.AppendExtra("else\n")
script.WriteRawImage("/boot", "recovery.img")
script.AppendExtra("""
set_stage("%(bcb_dev)s", "2/3");
reboot_now("%(bcb_dev)s", "");
endif;
endif;
""" % bcb_dev)
script.AddToZip(input_zip, output_zip)
WriteMetadata(metadata, output_zip)
@ -560,7 +617,8 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
OPTIONS.source_info_dict)
target_boot = common.GetBootableImage(
"/tmp/boot.img", "boot.img", OPTIONS.target_tmp, "BOOT")
updating_boot = (source_boot.data != target_boot.data)
updating_boot = (not OPTIONS.two_step and
(source_boot.data != target_boot.data))
source_recovery = common.GetBootableImage(
"/tmp/recovery.img", "recovery.img", OPTIONS.source_tmp, "RECOVERY",
@ -578,6 +636,46 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
AppendAssertions(script, OPTIONS.target_info_dict)
device_specific.IncrementalOTA_Assertions()
# Two-step incremental package strategy (in chronological order,
# which is *not* the order in which the generated script has
# things):
#
# if stage is not "2/3" or "3/3":
# do verification on current system
# write recovery image to boot partition
# set stage to "2/3"
# reboot to boot partition and restart recovery
# else if stage is "2/3":
# write recovery image to recovery partition
# set stage to "3/3"
# reboot to recovery partition and restart recovery
# else:
# (stage must be "3/3")
# perform update:
# patch system files, etc.
# force full install of new boot image
# set up system to update recovery partition on first boot
# complete script normally (allow recovery to mark itself finished and reboot)
if OPTIONS.two_step:
if not OPTIONS.info_dict.get("multistage_support", None):
assert False, "two-step packages not supported by this build"
fs = OPTIONS.info_dict["fstab"]["/misc"]
assert fs.fs_type.upper() == "EMMC", \
"two-step packages only supported on devices with EMMC /misc partitions"
bcb_dev = {"bcb_dev": fs.device}
common.ZipWriteStr(output_zip, "recovery.img", target_recovery.data)
script.AppendExtra("""
if get_stage("%(bcb_dev)s", "stage") == "2/3" then
""" % bcb_dev)
script.AppendExtra("sleep(20);\n");
script.WriteRawImage("/recovery", "recovery.img")
script.AppendExtra("""
set_stage("%(bcb_dev)s", "3/3");
reboot_now("%(bcb_dev)s", "recovery");
else if get_stage("%(bcb_dev)s", "stage") != "3/3" then
""" % bcb_dev)
script.Print("Verifying current system...")
device_specific.IncrementalOTA_VerifyBegin()
@ -615,10 +713,23 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
device_specific.IncrementalOTA_VerifyEnd()
if OPTIONS.two_step:
script.WriteRawImage("/boot", "recovery.img")
script.AppendExtra("""
set_stage("%(bcb_dev)s", "2/3");
reboot_now("%(bcb_dev)s", "");
else
""" % bcb_dev)
script.Comment("---- start making changes here ----")
device_specific.IncrementalOTA_InstallBegin()
if OPTIONS.two_step:
common.ZipWriteStr(output_zip, "boot.img", target_boot.data)
script.WriteRawImage("/boot", "boot.img")
print "writing full boot image (forced by two-step mode)"
if OPTIONS.wipe_user_data:
script.Print("Erasing user data...")
script.FormatPartition("/data")
@ -646,23 +757,24 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
so_far += tf.size
script.SetProgress(so_far / total_patch_size)
if updating_boot:
# Produce the boot image by applying a patch to the current
# contents of the boot partition, and write it back to the
# partition.
script.Print("Patching boot image...")
script.ApplyPatch("%s:%s:%d:%s:%d:%s"
% (boot_type, boot_device,
source_boot.size, source_boot.sha1,
target_boot.size, target_boot.sha1),
"-",
target_boot.size, target_boot.sha1,
source_boot.sha1, "patch/boot.img.p")
so_far += target_boot.size
script.SetProgress(so_far / total_patch_size)
print "boot image changed; including."
else:
print "boot image unchanged; skipping."
if not OPTIONS.two_step:
if updating_boot:
# Produce the boot image by applying a patch to the current
# contents of the boot partition, and write it back to the
# partition.
script.Print("Patching boot image...")
script.ApplyPatch("%s:%s:%d:%s:%d:%s"
% (boot_type, boot_device,
source_boot.size, source_boot.sha1,
target_boot.size, target_boot.sha1),
"-",
target_boot.size, target_boot.sha1,
source_boot.sha1, "patch/boot.img.p")
so_far += target_boot.size
script.SetProgress(so_far / total_patch_size)
print "boot image changed; including."
else:
print "boot image unchanged; skipping."
if updating_recovery:
# Recovery is generated as a patch using both the boot image
@ -747,6 +859,13 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
script.ApplyPatch("/"+fn, "-", tf.size, tf.sha1, sf.sha1, "patch/"+fn+".p")
script.SetPermissions("/system/build.prop", 0, 0, 0644, None, None)
if OPTIONS.two_step:
script.AppendExtra("""
set_stage("%(bcb_dev)s", "");
endif;
endif;
""" % bcb_dev)
script.AddToZip(target_zip, output_zip)
WriteMetadata(metadata, output_zip)
@ -773,12 +892,14 @@ def main(argv):
OPTIONS.aslr_mode = False
elif o in ("--worker_threads"):
OPTIONS.worker_threads = int(a)
elif o in ("-2", "--two_step"):
OPTIONS.two_step = True
else:
return False
return True
args = common.ParseOptions(argv, __doc__,
extra_opts="b:k:i:d:wne:a:",
extra_opts="b:k:i:d:wne:a:2",
extra_long_opts=["board_config=",
"package_key=",
"incremental_from=",
@ -787,6 +908,7 @@ def main(argv):
"extra_script=",
"worker_threads=",
"aslr_mode=",
"two_step",
],
extra_option_handler=option_handler)