From 6079cd014a65dca5cf6d2e3eaee5ccd85605d19b Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Fri, 2 Aug 2019 18:15:40 -0700 Subject: [PATCH] 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 --- fs_mgr/liblp/builder.cpp | 31 +++++++++++++++++++--------- fs_mgr/liblp/include/liblp/builder.h | 3 +++ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp index 247e3a92c..777743ca2 100644 --- a/fs_mgr/liblp/builder.cpp +++ b/fs_mgr/liblp/builder.cpp @@ -159,16 +159,27 @@ std::unique_ptr 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::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::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) { diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h index a2294efd7..3b229bde5 100644 --- a/fs_mgr/liblp/include/liblp/builder.h +++ b/fs_mgr/liblp/include/liblp/builder.h @@ -345,6 +345,9 @@ class MetadataBuilder { const std::vector& 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> partitions_;