From b937ead5d9a208079372b70a149aff66c7a607e1 Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Thu, 19 Oct 2017 16:51:53 -0700 Subject: [PATCH] releasetools: Work around the issue with mke2fs created images. When generating block based OTAs, we read files from the sparse image directly with the help of block map file. However, the block map info might not be accurate if the image is created with mke2fs. Because mke2fs may skip allocating actual blocks if they contain all zeros. ota_from_target_files.py consequently passes incomplete APK files to imgdiff, which fails to generate patches. This CL works around the issue by falling back from imgdiff to bsdiff on failures. We should figure out a better way in b/68016761 to remove the workaround, which would otherwise hide other issues in imgdiff. Bug: 67824829 Bug: 68016761 Test: ota_from_target_files.py passes on previously failing TF zips. Change-Id: Ib24c5b5f89812b97a0c87c6bf0dc147ae39bc92f --- tools/releasetools/blockimgdiff.py | 38 +++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py index b8123c09a3..c95512d273 100644 --- a/tools/releasetools/blockimgdiff.py +++ b/tools/releasetools/blockimgdiff.py @@ -717,6 +717,7 @@ class BlockImageDiff(object): diff_total = len(diff_queue) patches = [None] * diff_total error_messages = [] + warning_messages = [] if sys.stdout.isatty(): global diff_done diff_done = 0 @@ -750,16 +751,34 @@ class BlockImageDiff(object): with open(tgt_file, "wb") as fd: self.tgt.WriteRangeDataToFd(tgt_ranges, fd) + message = [] try: patch = compute_patch(src_file, tgt_file, imgdiff) except ValueError as e: + message.append( + "Failed to generate %s for %s: tgt=%s, src=%s:\n%s" % ( + "imgdiff" if imgdiff else "bsdiff", + xf.tgt_name if xf.tgt_name == xf.src_name else + xf.tgt_name + " (from " + xf.src_name + ")", + xf.tgt_ranges, xf.src_ranges, e.message)) + # TODO(b/68016761): Better handle the holes in mke2fs created images. + if imgdiff: + try: + patch = compute_patch(src_file, tgt_file, imgdiff=False) + message.append( + "Fell back and generated with bsdiff instead for %s" % ( + xf.tgt_name,)) + with lock: + warning_messages.extend(message) + del message[:] + except ValueError as e: + message.append( + "Also failed to generate with bsdiff for %s:\n%s" % ( + xf.tgt_name, e.message)) + + if message: with lock: - error_messages.append( - "Failed to generate %s for %s: tgt=%s, src=%s:\n%s" % ( - "imgdiff" if imgdiff else "bsdiff", - xf.tgt_name if xf.tgt_name == xf.src_name else - xf.tgt_name + " (from " + xf.src_name + ")", - xf.tgt_ranges, xf.src_ranges, e.message)) + error_messages.extend(message) with lock: patches[patch_index] = (xf_index, patch) @@ -781,8 +800,15 @@ class BlockImageDiff(object): if sys.stdout.isatty(): print('\n') + if warning_messages: + print('WARNING:') + print('\n'.join(warning_messages)) + print('\n\n\n') + if error_messages: + print('ERROR:') print('\n'.join(error_messages)) + print('\n\n\n') sys.exit(1) else: patches = []