Verify the extents for untouched dynamic partitions during partial update
For partial updates, the metadata for untouched dynamic partitions
are just copied over to the target slot. So, verifying the extents
of these partitions in the target metadata should be sufficient for
correctness. This saves the work to read & hash the bytes on these
partitions for each resumed update.
Bug: 151088567
Test: unit tests pass, apply a partial update
Change-Id: I9d40ed2643e145a1546ea17b146fcdcfb91f213f
diff --git a/dynamic_partition_control_android.cc b/dynamic_partition_control_android.cc
index 6817c21..ba749d9 100644
--- a/dynamic_partition_control_android.cc
+++ b/dynamic_partition_control_android.cc
@@ -293,9 +293,16 @@
std::unique_ptr<MetadataBuilder>
DynamicPartitionControlAndroid::LoadMetadataBuilder(
- const std::string& super_device, uint32_t source_slot) {
- return LoadMetadataBuilder(
- super_device, source_slot, BootControlInterface::kInvalidSlot);
+ const std::string& super_device, uint32_t slot) {
+ auto builder = MetadataBuilder::New(PartitionOpener(), super_device, slot);
+ if (builder == nullptr) {
+ LOG(WARNING) << "No metadata slot " << BootControlInterface::SlotName(slot)
+ << " in " << super_device;
+ return nullptr;
+ }
+ LOG(INFO) << "Loaded metadata from slot "
+ << BootControlInterface::SlotName(slot) << " in " << super_device;
+ return builder;
}
std::unique_ptr<MetadataBuilder>
@@ -303,26 +310,19 @@
const std::string& super_device,
uint32_t source_slot,
uint32_t target_slot) {
- std::unique_ptr<MetadataBuilder> builder;
- if (target_slot == BootControlInterface::kInvalidSlot) {
- builder =
- MetadataBuilder::New(PartitionOpener(), super_device, source_slot);
- } else {
- bool always_keep_source_slot = !target_supports_snapshot_;
- builder = MetadataBuilder::NewForUpdate(PartitionOpener(),
- super_device,
- source_slot,
- target_slot,
- always_keep_source_slot);
- }
-
+ bool always_keep_source_slot = !target_supports_snapshot_;
+ auto builder = MetadataBuilder::NewForUpdate(PartitionOpener(),
+ super_device,
+ source_slot,
+ target_slot,
+ always_keep_source_slot);
if (builder == nullptr) {
LOG(WARNING) << "No metadata slot "
<< BootControlInterface::SlotName(source_slot) << " in "
<< super_device;
return nullptr;
}
- LOG(INFO) << "Loaded metadata from slot "
+ LOG(INFO) << "Created metadata for new update from slot "
<< BootControlInterface::SlotName(source_slot) << " in "
<< super_device;
return builder;
@@ -495,6 +495,7 @@
}
}
+ // TODO(xunchang) support partial update on non VAB enabled devices.
TEST_AND_RETURN_FALSE(PrepareDynamicPartitionsForUpdate(
source_slot, target_slot, manifest, delete_source));
@@ -1113,6 +1114,28 @@
return true;
}
+bool DynamicPartitionControlAndroid::VerifyExtentsForUntouchedPartitions(
+ uint32_t source_slot,
+ uint32_t target_slot,
+ const std::vector<std::string>& partitions) {
+ std::string device_dir_str;
+ TEST_AND_RETURN_FALSE(GetDeviceDir(&device_dir_str));
+ base::FilePath device_dir(device_dir_str);
+
+ auto source_super_device =
+ device_dir.Append(GetSuperPartitionName(source_slot)).value();
+ auto source_builder = LoadMetadataBuilder(source_super_device, source_slot);
+ TEST_AND_RETURN_FALSE(source_builder != nullptr);
+
+ auto target_super_device =
+ device_dir.Append(GetSuperPartitionName(target_slot)).value();
+ auto target_builder = LoadMetadataBuilder(target_super_device, target_slot);
+ TEST_AND_RETURN_FALSE(target_builder != nullptr);
+
+ return MetadataBuilder::VerifyExtentsAgainstSourceMetadata(
+ *source_builder, source_slot, *target_builder, target_slot, partitions);
+}
+
bool DynamicPartitionControlAndroid::ExpectMetadataMounted() {
// No need to mount metadata for non-Virtual A/B devices.
if (!GetVirtualAbFeatureFlag().IsEnabled()) {