aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTao Bao <tbao@google.com>2015-09-02 10:28:08 -0700
committerThe Android Automerger <android-build@google.com>2015-09-03 10:44:04 -0700
commit7a61dd9f2f31ff4c2beaf15bb71c0f5b012db0c0 (patch)
tree6d6031844f3c83c10a09094c3799abefb7873e17
parentb8e67f12fcbac5529b820b837307be802a3a7af5 (diff)
downloadbuild-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.py11
-rwxr-xr-xtools/releasetools/ota_from_target_files.py31
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...")