diff options
author | Tao Bao <tbao@google.com> | 2015-09-02 10:28:08 -0700 |
---|---|---|
committer | The Android Automerger <android-build@google.com> | 2015-09-03 10:44:04 -0700 |
commit | 7a61dd9f2f31ff4c2beaf15bb71c0f5b012db0c0 (patch) | |
tree | 6d6031844f3c83c10a09094c3799abefb7873e17 | |
parent | b8e67f12fcbac5529b820b837307be802a3a7af5 (diff) | |
download | build-7a61dd9f2f31ff4c2beaf15bb71c0f5b012db0c0.tar.gz |
releasetools: Fix the bug in symlink deletion.
For file-based OTAs, symlinks in the source build but not in the target
build will be deleted. However, if a symlink is replaced by a regular
file in the target build, the file will be accidentally deleted when
applying (resuming) the same package again.
Verify the checksum of a symlink that will be unpacked or renamed to.
Delete the file only if it doesn't have the target checksum.
Bug: 23646151
Change-Id: I77bae035e39f2e0be25f7f6d71c5882464e3d50f
(cherry picked from commit 84006eacd05e3f2784a0ecdf36609767f2c34044)
-rw-r--r-- | tools/releasetools/edify_generator.py | 11 | ||||
-rwxr-xr-x | tools/releasetools/ota_from_target_files.py | 31 |
2 files changed, 38 insertions, 4 deletions
diff --git a/tools/releasetools/edify_generator.py b/tools/releasetools/edify_generator.py index 566e68752f..a52e3283a5 100644 --- a/tools/releasetools/edify_generator.py +++ b/tools/releasetools/edify_generator.py @@ -243,6 +243,15 @@ class EdifyGenerator(object): cmd = "delete(" + ",\0".join(['"%s"' % (i,) for i in file_list]) + ");" self.script.append(self.WordWrap(cmd)) + def DeleteFilesIfNotMatching(self, file_list): + """Delete the file in file_list if not matching the checksum.""" + if not file_list: + return + for name, sha1 in file_list: + cmd = ('sha1_check(read_file("{name}"), "{sha1}") || ' + 'delete("{name}");'.format(name=name, sha1=sha1)) + self.script.append(self.WordWrap(cmd)) + def RenameFile(self, srcfile, tgtfile): """Moves a file from one location to another.""" if self.info.get("update_rename_support", False): @@ -254,7 +263,7 @@ class EdifyGenerator(object): """Prepend an action with an apply_patch_check in order to skip the action if the file exists. Used when a patch is later renamed.""" - cmd = ('sha1_check(read_file("%s"), %s) || ' % (tgtfile, tgtsha1)) + cmd = ('sha1_check(read_file("%s"), %s) ||' % (tgtfile, tgtsha1)) self.script.append(self.WordWrap(cmd)) def ApplyPatch(self, srcfile, tgtfile, tgtsize, tgtsha1, *patchpairs): diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py index 531a728dbd..9951b39378 100755 --- a/tools/releasetools/ota_from_target_files.py +++ b/tools/releasetools/ota_from_target_files.py @@ -1384,11 +1384,36 @@ else # Delete all the symlinks in source that aren't in target. This # needs to happen before verbatim files are unpacked, in case a # symlink in the source is replaced by a real file in the target. - to_delete = [] + + # If a symlink in the source will be replaced by a regular file, we cannot + # delete the symlink/file in case the package gets applied again. For such + # a symlink, we prepend a sha1_check() to detect if it has been updated. + # (Bug: 23646151) + replaced_symlinks = dict() + if system_diff: + for i in system_diff.verbatim_targets: + replaced_symlinks["/%s" % (i[0],)] = i[2] + if vendor_diff: + for i in vendor_diff.verbatim_targets: + replaced_symlinks["/%s" % (i[0],)] = i[2] + + if system_diff: + for tf in system_diff.renames.values(): + replaced_symlinks["/%s" % (tf.name,)] = tf.sha1 + if vendor_diff: + for tf in vendor_diff.renames.values(): + replaced_symlinks["/%s" % (tf.name,)] = tf.sha1 + + always_delete = [] + may_delete = [] for dest, link in source_symlinks: if link not in target_symlinks_d: - to_delete.append(link) - script.DeleteFiles(to_delete) + if link in replaced_symlinks: + may_delete.append((link, replaced_symlinks[link])) + else: + always_delete.append(link) + script.DeleteFiles(always_delete) + script.DeleteFilesIfNotMatching(may_delete) if system_diff.verbatim_targets: script.Print("Unpacking new system files...") |