liblp: refactor MetadataBuilder::NewForUpdate

Move the logic for retrofit DAP to its new function. The new flow
in NewForUpdate is:
    metadata = ReadMetadata();
    if (retrofit dap) UpdateMetadataForOtherSuper(metadata)
    return metadata;

Test: liblp_test_static
Change-Id: I6890fff3a7c44ebe2004de96b2ccbe1e8ce37546
This commit is contained in:
Yifan Hong 2019-08-02 18:15:40 -07:00
parent 5b4b38cee0
commit 6079cd014a
2 changed files with 24 additions and 10 deletions

View File

@ -159,16 +159,27 @@ std::unique_ptr<MetadataBuilder> MetadataBuilder::NewForUpdate(const IPartitionO
return nullptr;
}
// On non-retrofit devices there is only one location for metadata: the
// super partition. update_engine will remove and resize partitions as
// needed. On the other hand, for retrofit devices, we'll need to
// translate block device and group names to update their slot suffixes.
// On retrofit DAP devices, modify the metadata so that it is suitable for being written
// to the target slot later. We detect retrofit DAP devices by checking the super partition
// name and system properties.
// See comments for UpdateMetadataForOtherSuper.
auto super_device = GetMetadataSuperBlockDevice(*metadata.get());
if (GetBlockDevicePartitionName(*super_device) == "super" ||
!IsRetrofitDynamicPartitionsDevice()) {
return New(*metadata.get(), &opener);
if (GetBlockDevicePartitionName(*super_device) != "super" &&
IsRetrofitDynamicPartitionsDevice()) {
if (!UpdateMetadataForOtherSuper(metadata.get(), source_slot_number, target_slot_number)) {
return nullptr;
}
}
return New(*metadata.get(), &opener);
}
// For retrofit DAP devices, there are (conceptually) two super partitions. We'll need to translate
// block device and group names to update their slot suffixes.
// (On the other hand, On non-retrofit DAP devices there is only one location for metadata: the
// super partition. update_engine will remove and resize partitions as needed.)
bool MetadataBuilder::UpdateMetadataForOtherSuper(LpMetadata* metadata, uint32_t source_slot_number,
uint32_t target_slot_number) {
// Clear partitions and extents, since they have no meaning on the target
// slot. We also clear groups since they are re-added during OTA.
metadata->partitions.clear();
@ -188,7 +199,7 @@ std::unique_ptr<MetadataBuilder> MetadataBuilder::NewForUpdate(const IPartitionO
// refers to a target or unknown block device.
LERROR << "Invalid block device for slot " << source_slot_suffix << ": "
<< partition_name;
return nullptr;
return false;
}
std::string new_name =
partition_name.substr(0, partition_name.size() - slot_suffix.size()) +
@ -197,12 +208,12 @@ std::unique_ptr<MetadataBuilder> MetadataBuilder::NewForUpdate(const IPartitionO
auto new_device = source_block_device;
if (!UpdateBlockDevicePartitionName(&new_device, new_name)) {
LERROR << "Partition name too long: " << new_name;
return nullptr;
return false;
}
metadata->block_devices.emplace_back(new_device);
}
return New(*metadata.get(), &opener);
return true;
}
MetadataBuilder::MetadataBuilder() : auto_slot_suffixing_(false) {

View File

@ -345,6 +345,9 @@ class MetadataBuilder {
const std::vector<Interval>& free_list,
uint64_t sectors_needed) const;
static bool UpdateMetadataForOtherSuper(LpMetadata* metadata, uint32_t source_slot_number,
uint32_t target_slot_number);
LpMetadataGeometry geometry_;
LpMetadataHeader header_;
std::vector<std::unique_ptr<Partition>> partitions_;