Check block0 for remounting partition R/W
Add a function check_first_block to read block0 and output a message on screen if the device has been remounted. The function is called for version >= 4 only; it executes after a failing block verification and before recovery attempts. Bug: 21124327 Change-Id: I49dc0b861c702698896a2495ca094215705d4650
This commit is contained in:
@@ -1238,9 +1238,6 @@ class BlockDifference(object):
|
|||||||
self.partition = partition
|
self.partition = partition
|
||||||
self.check_first_block = check_first_block
|
self.check_first_block = check_first_block
|
||||||
|
|
||||||
# Due to http://b/20939131, check_first_block is disabled temporarily.
|
|
||||||
assert not self.check_first_block
|
|
||||||
|
|
||||||
if version is None:
|
if version is None:
|
||||||
version = 1
|
version = 1
|
||||||
if OPTIONS.info_dict:
|
if OPTIONS.info_dict:
|
||||||
@@ -1304,14 +1301,8 @@ class BlockDifference(object):
|
|||||||
script.AppendExtra(('if (range_sha1("%s", "%s") == "%s" || '
|
script.AppendExtra(('if (range_sha1("%s", "%s") == "%s" || '
|
||||||
'block_image_verify("%s", '
|
'block_image_verify("%s", '
|
||||||
'package_extract_file("%s.transfer.list"), '
|
'package_extract_file("%s.transfer.list"), '
|
||||||
'"%s.new.dat", "%s.patch.dat") || '
|
'"%s.new.dat", "%s.patch.dat")) then') % (
|
||||||
'(block_image_recover("%s", "%s") && '
|
|
||||||
'block_image_verify("%s", '
|
|
||||||
'package_extract_file("%s.transfer.list"), '
|
|
||||||
'"%s.new.dat", "%s.patch.dat"))) then') % (
|
|
||||||
self.device, ranges_str, self.src.TotalSha1(),
|
self.device, ranges_str, self.src.TotalSha1(),
|
||||||
self.device, partition, partition, partition,
|
|
||||||
self.device, ranges_str,
|
|
||||||
self.device, partition, partition, partition))
|
self.device, partition, partition, partition))
|
||||||
elif self.version == 3:
|
elif self.version == 3:
|
||||||
script.AppendExtra(('if (range_sha1("%s", "%s") == "%s" || '
|
script.AppendExtra(('if (range_sha1("%s", "%s") == "%s" || '
|
||||||
@@ -1326,20 +1317,34 @@ class BlockDifference(object):
|
|||||||
script.Print('Verified %s image...' % (partition,))
|
script.Print('Verified %s image...' % (partition,))
|
||||||
script.AppendExtra('else')
|
script.AppendExtra('else')
|
||||||
|
|
||||||
# When generating incrementals for the system and vendor partitions,
|
if self.version >= 4:
|
||||||
# explicitly check the first block (which contains the superblock) of
|
|
||||||
# the partition to see if it's what we expect. If this check fails,
|
# Bug: 21124327
|
||||||
# give an explicit log message about the partition having been
|
# When generating incrementals for the system and vendor partitions in
|
||||||
# remounted R/W (the most likely explanation) and the need to flash to
|
# version 4 or newer, explicitly check the first block (which contains
|
||||||
# get OTAs working again.
|
# the superblock) of the partition to see if it's what we expect. If
|
||||||
|
# this check fails, give an explicit log message about the partition
|
||||||
|
# having been remounted R/W (the most likely explanation).
|
||||||
if self.check_first_block:
|
if self.check_first_block:
|
||||||
self._CheckFirstBlock(script)
|
script.AppendExtra('check_first_block("%s");' % (self.device,))
|
||||||
|
|
||||||
|
# If version >= 4, try block recovery before abort update
|
||||||
|
script.AppendExtra((
|
||||||
|
'ifelse (block_image_recover("{device}", "{ranges}") && '
|
||||||
|
'block_image_verify("{device}", '
|
||||||
|
'package_extract_file("{partition}.transfer.list"), '
|
||||||
|
'"{partition}.new.dat", "{partition}.patch.dat"), '
|
||||||
|
'ui_print("{partition} recovered successfully."), '
|
||||||
|
'abort("{partition} partition fails to recover"));\n'
|
||||||
|
'endif;').format(device=self.device, ranges=ranges_str,
|
||||||
|
partition=partition))
|
||||||
|
|
||||||
# Abort the OTA update. Note that the incremental OTA cannot be applied
|
# Abort the OTA update. Note that the incremental OTA cannot be applied
|
||||||
# even if it may match the checksum of the target partition.
|
# even if it may match the checksum of the target partition.
|
||||||
# a) If version < 3, operations like move and erase will make changes
|
# a) If version < 3, operations like move and erase will make changes
|
||||||
# unconditionally and damage the partition.
|
# unconditionally and damage the partition.
|
||||||
# b) If version >= 3, it won't even reach here.
|
# b) If version >= 3, it won't even reach here.
|
||||||
|
else:
|
||||||
script.AppendExtra(('abort("%s partition has unexpected contents");\n'
|
script.AppendExtra(('abort("%s partition has unexpected contents");\n'
|
||||||
'endif;') % (partition,))
|
'endif;') % (partition,))
|
||||||
|
|
||||||
@@ -1410,22 +1415,9 @@ class BlockDifference(object):
|
|||||||
|
|
||||||
return ctx.hexdigest()
|
return ctx.hexdigest()
|
||||||
|
|
||||||
# TODO(tbao): Due to http://b/20939131, block 0 may be changed without
|
|
||||||
# remounting R/W. Will change the checking to a finer-grained way to
|
|
||||||
# mask off those bits.
|
|
||||||
def _CheckFirstBlock(self, script):
|
|
||||||
r = rangelib.RangeSet((0, 1))
|
|
||||||
srchash = self._HashBlocks(self.src, r)
|
|
||||||
|
|
||||||
script.AppendExtra(('(range_sha1("%s", "%s") == "%s") || '
|
|
||||||
'abort("%s has been remounted R/W; '
|
|
||||||
'reflash device to reenable OTA updates");')
|
|
||||||
% (self.device, r.to_string_raw(), srchash,
|
|
||||||
self.device))
|
|
||||||
|
|
||||||
DataImage = blockimgdiff.DataImage
|
DataImage = blockimgdiff.DataImage
|
||||||
|
|
||||||
|
|
||||||
# map recovery.fstab's fs_types to mount/format "partition types"
|
# map recovery.fstab's fs_types to mount/format "partition types"
|
||||||
PARTITION_TYPES = {
|
PARTITION_TYPES = {
|
||||||
"yaffs2": "MTD",
|
"yaffs2": "MTD",
|
||||||
|
@@ -811,7 +811,12 @@ def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip):
|
|||||||
int(i) for i in
|
int(i) for i in
|
||||||
OPTIONS.info_dict.get("blockimgdiff_versions", "1").split(","))
|
OPTIONS.info_dict.get("blockimgdiff_versions", "1").split(","))
|
||||||
|
|
||||||
|
# Check first block of system partition for remount R/W only if
|
||||||
|
# disk type is ext4
|
||||||
|
system_partition = OPTIONS.source_info_dict["fstab"]["/system"]
|
||||||
|
check_first_block = system_partition.fs_type=="ext4"
|
||||||
system_diff = common.BlockDifference("system", system_tgt, system_src,
|
system_diff = common.BlockDifference("system", system_tgt, system_src,
|
||||||
|
check_first_block,
|
||||||
version=blockimgdiff_version)
|
version=blockimgdiff_version)
|
||||||
|
|
||||||
if HasVendorPartition(target_zip):
|
if HasVendorPartition(target_zip):
|
||||||
@@ -821,7 +826,13 @@ def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip):
|
|||||||
OPTIONS.source_info_dict)
|
OPTIONS.source_info_dict)
|
||||||
vendor_tgt = GetImage("vendor", OPTIONS.target_tmp,
|
vendor_tgt = GetImage("vendor", OPTIONS.target_tmp,
|
||||||
OPTIONS.target_info_dict)
|
OPTIONS.target_info_dict)
|
||||||
|
|
||||||
|
# Check first block of vendor partition for remount R/W only if
|
||||||
|
# disk type is ext4
|
||||||
|
vendor_partition = OPTIONS.source_info_dict["fstab"]["/vendor"]
|
||||||
|
check_first_block = vendor_partition.fs_type=="ext4"
|
||||||
vendor_diff = common.BlockDifference("vendor", vendor_tgt, vendor_src,
|
vendor_diff = common.BlockDifference("vendor", vendor_tgt, vendor_src,
|
||||||
|
check_first_block,
|
||||||
version=blockimgdiff_version)
|
version=blockimgdiff_version)
|
||||||
else:
|
else:
|
||||||
vendor_diff = None
|
vendor_diff = None
|
||||||
|
Reference in New Issue
Block a user