diff --git a/core/Makefile b/core/Makefile index a59159d9dc..a89c120ec3 100644 --- a/core/Makefile +++ b/core/Makefile @@ -869,6 +869,7 @@ $(BUILT_TARGET_FILES_PACKAGE): \ $(INSTALLED_ANDROID_INFO_TXT_TARGET) \ $(built_ota_tools) \ $(APKCERTS_FILE) \ + $(HOST_OUT_EXECUTABLES)/fs_config \ | $(ACP) @echo "Package target files: $@" $(hide) rm -rf $@ $(zip_root) @@ -934,6 +935,10 @@ endif $(hide) echo "$(tool_extensions)" > $(zip_root)/META/tool-extensions.txt @# Zip everything up, preserving symlinks $(hide) (cd $(zip_root) && zip -qry ../$(notdir $@) .) + @# Run fs_config on all the system files in the zip, and save the output + $(hide) zipinfo -1 $@ | awk -F/ 'BEGIN { OFS="/" } /^SYSTEM\// {$$1 = "system"; print}' | $(HOST_OUT_EXECUTABLES)/fs_config > $(zip_root)/META/filesystem_config.txt + $(hide) (cd $(zip_root) && zip -q ../$(notdir $@) META/filesystem_config.txt) + target-files-package: $(BUILT_TARGET_FILES_PACKAGE) diff --git a/tools/releasetools/ota_from_target_files b/tools/releasetools/ota_from_target_files index 70ab55f8e3..0454d6ffc9 100755 --- a/tools/releasetools/ota_from_target_files +++ b/tools/releasetools/ota_from_target_files @@ -137,26 +137,41 @@ class Item: return cls.ITEMS[name] @classmethod - def GetMetadata(cls): - """Run the external 'fs_config' program to determine the desired - uid, gid, and mode for every Item object.""" - p = common.Run(["fs_config"], stdin=subprocess.PIPE, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - suffix = { False: "", True: "/" } - input = "".join(["%s%s\n" % (i.name, suffix[i.dir]) - for i in cls.ITEMS.itervalues() if i.name]) - output, error = p.communicate(input) - assert not error + def GetMetadata(cls, input_zip): + + try: + # See if the target_files contains a record of what the uid, + # gid, and mode is supposed to be. + output = input_zip.read("META/filesystem_config.txt") + except KeyError: + # Run the external 'fs_config' program to determine the desired + # uid, gid, and mode for every Item object. Note this uses the + # one in the client now, which might not be the same as the one + # used when this target_files was built. + p = common.Run(["fs_config"], stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + suffix = { False: "", True: "/" } + input = "".join(["%s%s\n" % (i.name, suffix[i.dir]) + for i in cls.ITEMS.itervalues() if i.name]) + output2, error = p.communicate(input) + assert not error for line in output.split("\n"): if not line: continue name, uid, gid, mode = line.split() - i = cls.ITEMS[name] - i.uid = int(uid) - i.gid = int(gid) - i.mode = int(mode, 8) - if i.dir: - i.children.sort(key=lambda i: i.name) + i = cls.ITEMS.get(name, None) + if i is not None: + i.uid = int(uid) + i.gid = int(gid) + i.mode = int(mode, 8) + if i.dir: + i.children.sort(key=lambda i: i.name) + + # set metadata for the files generated by this script. + i = cls.ITEMS.get("system/recovery-from-boot.p", None) + if i: i.uid, i.gid, i.mode = 0, 0, 0644 + i = cls.ITEMS.get("system/etc/install-recovery.sh", None) + if i: i.uid, i.gid, i.mode = 0, 0, 0544 def CountChildMetadata(self): """Count up the (uid, gid, mode) tuples for all children and @@ -369,16 +384,9 @@ def WriteFullOTAPackage(input_zip, output_zip): os.path.join(OPTIONS.input_tmp, "BOOT"))) recovery_img = File("recovery.img", common.BuildBootableImage( os.path.join(OPTIONS.input_tmp, "RECOVERY"))) - i = MakeRecoveryPatch(output_zip, recovery_img, boot_img) + MakeRecoveryPatch(output_zip, recovery_img, boot_img) - Item.GetMetadata() - - # GetMetadata uses the data in android_filesystem_config.h to assign - # the uid/gid/mode of all files. We want to override that for the - # recovery patching shell script to make it executable. - i.uid = 0 - i.gid = 0 - i.mode = 0544 + Item.GetMetadata(input_zip) Item.Get("system").SetPermissions(script) common.CheckSize(boot_img.data, "boot.img") @@ -746,8 +754,7 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip): # partition, include the binaries and image files from recovery in # the boot image (though not in the ramdisk) so they can be used # as fodder for constructing the recovery image. - recovery_sh_item = MakeRecoveryPatch(output_zip, - target_recovery, target_boot) + MakeRecoveryPatch(output_zip, target_recovery, target_boot) script.DeleteFiles(["/system/recovery-from-boot.p", "/system/etc/install-recovery.sh"]) print "recovery image changed; including as patch from boot." @@ -760,11 +767,7 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip): target_symlinks_d = dict([(i[1], i[0]) for i in target_symlinks]) temp_script = script.MakeTemporary() - Item.GetMetadata() - if updating_recovery: - recovery_sh_item.uid = 0 - recovery_sh_item.gid = 0 - recovery_sh_item.mode = 0544 + Item.GetMetadata(target_zip) Item.Get("system").SetPermissions(temp_script) # Note that this call will mess up the tree of Items, so make sure