Support updateable groups.
Adds updateable group support to OTA.
* DeltaPerformer combines partition sizes with
dynamic_partition_metadata to
BootControlInterface::PartitionMetadata.
* BootControlAndroid::InitPartitionMetadata:
* Copy all groups / partitions from source metadata slot
* Remove all groups / partitions mentioned in the manifest (of the
target slot)
* Re-add all groups / partitions mentioned in the manifest.
* BootControlAndroid::InitPartitionMetadata can check
the incoming PartitionMetadata to see if a partition is dynamic
or not. The guessing logic is completely removed.
* Because a partition is removed then re-added, there is no need
for preserving the entry with size 0 to indicate that a partition
is removed. When update_engine sees a partition in a group "foo" on
the device, but manifest contains group "foo" without the partition,
it removes the partition.
* Hence, Removing a partition does NOT require keeping the entry (i.e.
RemovePartition is used instead of ShrinkPartition(0) ). This makes
retrofitting dynamic partitions on older devices easier.
The following is now allowed:
- Adding / removing / resizing partitions
- Adding / resizing groups
It is not allowed to remove a group, but a group can always be resized
to zero to deprecate it.
Test: update_engine_unittests
Bug: 117182932
Change-Id: I39d77f1d1d1fc52fc245f3de699635e6a429015e
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index 7dec48f..7a19374 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -944,8 +944,30 @@
}
BootControlInterface::PartitionMetadata partition_metadata;
- for (const InstallPlan::Partition& partition : install_plan_->partitions) {
- partition_metadata.emplace(partition.name, partition.target_size);
+ if (manifest_.has_dynamic_partition_metadata()) {
+ std::map<string, uint64_t> partition_sizes;
+ for (const InstallPlan::Partition& partition : install_plan_->partitions) {
+ partition_sizes.emplace(partition.name, partition.target_size);
+ }
+ for (const auto& group : manifest_.dynamic_partition_metadata().groups()) {
+ BootControlInterface::PartitionMetadata::Group e;
+ e.name = group.name();
+ e.size = group.size();
+ for (const auto& partition_name : group.partition_names()) {
+ auto it = partition_sizes.find(partition_name);
+ if (it == partition_sizes.end()) {
+ // TODO(tbao): Support auto-filling partition info for framework-only
+ // OTA.
+ LOG(ERROR) << "dynamic_partition_metadata contains partition "
+ << partition_name
+ << " but it is not part of the manifest. "
+ << "This is not supported.";
+ return false;
+ }
+ e.partitions.push_back({partition_name, it->second});
+ }
+ partition_metadata.groups.push_back(std::move(e));
+ }
}
if (!boot_control_->InitPartitionMetadata(install_plan_->target_slot,
@@ -1676,6 +1698,16 @@
return ErrorCode::kPayloadTimestampError;
}
+ if (major_payload_version_ == kChromeOSMajorPayloadVersion) {
+ if (manifest_.has_dynamic_partition_metadata()) {
+ LOG(ERROR)
+ << "Should not contain dynamic_partition_metadata for major version "
+ << kChromeOSMajorPayloadVersion
+ << ". Please use major version 2 or above.";
+ return ErrorCode::kPayloadMismatchedType;
+ }
+ }
+
// TODO(garnold) we should be adding more and more manifest checks, such as
// partition boundaries etc (see chromium-os:37661).