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
This commit is contained in:
Tao Bao 2017-10-19 16:51:53 -07:00
parent 96929d691e
commit b937ead5d9
1 changed files with 32 additions and 6 deletions

View File

@ -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 = []