diff options
author | Yifan Hong <elsk@google.com> | 2018-11-09 16:50:51 -0800 |
---|---|---|
committer | Yifan Hong <elsk@google.com> | 2018-11-15 19:01:41 +0000 |
commit | 6e706b165a15e77488ef0009d76680c2f280477f (patch) | |
tree | 005297298da418c19011421c2413aabfd8ec86b7 /dynamic_partition_control_android.cc | |
parent | 9edcd045830a9fc7ac22622759b8378929cb7c66 (diff) |
DynamicPartitionControl: support retrofit devices
On retrofit devices:
* The retrofit update includes block devices at source
slot (for example, system_a, vendor_a, product_a).
This is done automatically because the retrofit update
does not look different from regular updates in OTA
client's perspective.
* The first update after the retrofit update includes
the rest of the block devices (in the above example,
system_b, vendor_b and product_b).
In order to do the second,
* use NewForUpdate() API from liblp to automatically
include block devices at the target slot when the metadata
is loaded.
* Use FlashPartitionTable() API to flash metadata to system_b
directly without reading existing metadata from it.
Test: manual OTA on retrofit devices
Bug: 118506262
Change-Id: Ib2c15b8a1a04271320bfef408813723a5b2a7bd7
Diffstat (limited to 'dynamic_partition_control_android.cc')
-rw-r--r-- | dynamic_partition_control_android.cc | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/dynamic_partition_control_android.cc b/dynamic_partition_control_android.cc index 38c67594..93a0fae6 100644 --- a/dynamic_partition_control_android.cc +++ b/dynamic_partition_control_android.cc @@ -37,10 +37,13 @@ using android::dm::DmDeviceState; using android::fs_mgr::CreateLogicalPartition; using android::fs_mgr::DestroyLogicalPartition; using android::fs_mgr::MetadataBuilder; +using android::fs_mgr::PartitionOpener; namespace chromeos_update_engine { -constexpr char kUseDynamicPartitions[] = "ro.boot.logical_partitions"; +constexpr char kUseDynamicPartitions[] = "ro.boot.dynamic_partitions"; +constexpr char kRetrfoitDynamicPartitions[] = + "ro.boot.dynamic_partitions_retrofit"; constexpr uint64_t kMapTimeoutMillis = 1000; DynamicPartitionControlAndroid::~DynamicPartitionControlAndroid() { @@ -51,6 +54,10 @@ bool DynamicPartitionControlAndroid::IsDynamicPartitionsEnabled() { return GetBoolProperty(kUseDynamicPartitions, false); } +static bool IsDynamicPartitionsRetrofit() { + return GetBoolProperty(kRetrfoitDynamicPartitions, false); +} + bool DynamicPartitionControlAndroid::MapPartitionOnDeviceMapper( const std::string& super_device, const std::string& target_partition_name, @@ -122,8 +129,20 @@ bool DynamicPartitionControlAndroid::GetDmDevicePathByName( std::unique_ptr<MetadataBuilder> DynamicPartitionControlAndroid::LoadMetadataBuilder( - const std::string& super_device, uint32_t source_slot) { - auto builder = MetadataBuilder::New(super_device, source_slot); + const std::string& super_device, + uint32_t source_slot, + uint32_t target_slot) { + std::unique_ptr<MetadataBuilder> builder; + + if (target_slot != BootControlInterface::kInvalidSlot && + IsDynamicPartitionsRetrofit()) { + builder = MetadataBuilder::NewForUpdate( + PartitionOpener(), super_device, source_slot, target_slot); + } else { + builder = + MetadataBuilder::New(PartitionOpener(), super_device, source_slot); + } + if (builder == nullptr) { LOG(WARNING) << "No metadata slot " << BootControlInterface::SlotName(source_slot) << " in " @@ -148,16 +167,24 @@ bool DynamicPartitionControlAndroid::StoreMetadata( return false; } - if (!UpdatePartitionTable(super_device, *metadata, target_slot)) { - LOG(ERROR) << "Cannot write metadata to slot " - << BootControlInterface::SlotName(target_slot) << " in " - << super_device; - return false; + if (IsDynamicPartitionsRetrofit()) { + if (!FlashPartitionTable(super_device, *metadata)) { + LOG(ERROR) << "Cannot write metadata to " << super_device; + return false; + } + LOG(INFO) << "Written metadata to " << super_device; + } else { + if (!UpdatePartitionTable(super_device, *metadata, target_slot)) { + LOG(ERROR) << "Cannot write metadata to slot " + << BootControlInterface::SlotName(target_slot) << " in " + << super_device; + return false; + } + LOG(INFO) << "Copied metadata to slot " + << BootControlInterface::SlotName(target_slot) << " in " + << super_device; } - LOG(INFO) << "Copied metadata to slot " - << BootControlInterface::SlotName(target_slot) << " in " - << super_device; return true; } |