diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp index 25a042fb6..c12e3b222 100644 --- a/fs_mgr/liblp/builder.cpp +++ b/fs_mgr/liblp/builder.cpp @@ -30,8 +30,8 @@ namespace android { namespace fs_mgr { -bool MetadataBuilder::sABOverrideSet; -bool MetadataBuilder::sABOverrideValue; +std::optional MetadataBuilder::sABOverride; +std::optional MetadataBuilder::sRetrofitDap; static const std::string kDefaultGroup = "default"; @@ -169,7 +169,8 @@ std::unique_ptr MetadataBuilder::NewForUpdate(const IPartitionO // needed. On the other hand, for retrofit devices, we'll need to // translate block device and group names to update their slot suffixes. auto super_device = GetMetadataSuperBlockDevice(*metadata.get()); - if (GetBlockDevicePartitionName(*super_device) == "super") { + if (GetBlockDevicePartitionName(*super_device) == "super" || + !IsRetrofitDynamicPartitionsDevice()) { return New(*metadata.get(), &opener); } @@ -210,8 +211,11 @@ std::unique_ptr MetadataBuilder::NewForUpdate(const IPartitionO } void MetadataBuilder::OverrideABForTesting(bool ab_device) { - sABOverrideSet = true; - sABOverrideValue = ab_device; + sABOverride = ab_device; +} + +void MetadataBuilder::OverrideRetrofitDynamicParititonsForTesting(bool retrofit) { + sRetrofitDap = retrofit; } MetadataBuilder::MetadataBuilder() : auto_slot_suffixing_(false) { @@ -580,7 +584,8 @@ bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t aligned_size) CHECK_NE(sectors_per_block, 0); CHECK(sectors_needed % sectors_per_block == 0); - if (IsABDevice() && !IsRetrofitDevice() && GetPartitionSlotSuffix(partition->name()) == "_b") { + if (IsABDevice() && !IsRetrofitMetadata() && + GetPartitionSlotSuffix(partition->name()) == "_b") { // Allocate "a" partitions top-down and "b" partitions bottom-up, to // minimize fragmentation during OTA. free_regions = PrioritizeSecondHalfOfSuper(free_regions); @@ -1044,14 +1049,21 @@ void MetadataBuilder::SetAutoSlotSuffixing() { auto_slot_suffixing_ = true; } -bool MetadataBuilder::IsABDevice() const { - if (sABOverrideSet) { - return sABOverrideValue; +bool MetadataBuilder::IsABDevice() { + if (sABOverride.has_value()) { + return *sABOverride; } return !android::base::GetProperty("ro.boot.slot_suffix", "").empty(); } -bool MetadataBuilder::IsRetrofitDevice() const { +bool MetadataBuilder::IsRetrofitDynamicPartitionsDevice() { + if (sRetrofitDap.has_value()) { + return *sRetrofitDap; + } + return !android::base::GetBoolProperty("ro.boot.dynamic_partitions_retrofit", false); +} + +bool MetadataBuilder::IsRetrofitMetadata() const { return GetBlockDevicePartitionName(block_devices_[0]) != LP_METADATA_DEFAULT_PARTITION_NAME; } diff --git a/fs_mgr/liblp/builder_test.cpp b/fs_mgr/liblp/builder_test.cpp index fd16e90b6..377ec685b 100644 --- a/fs_mgr/liblp/builder_test.cpp +++ b/fs_mgr/liblp/builder_test.cpp @@ -27,7 +27,10 @@ using ::testing::ElementsAre; class Environment : public ::testing::Environment { public: - void SetUp() override { MetadataBuilder::OverrideABForTesting(false); } + void SetUp() override { + MetadataBuilder::OverrideABForTesting(false); + MetadataBuilder::OverrideRetrofitDynamicParititonsForTesting(false); + } }; int main(int argc, char** argv) { @@ -38,8 +41,14 @@ int main(int argc, char** argv) { class BuilderTest : public ::testing::Test { public: - void SetUp() override { MetadataBuilder::OverrideABForTesting(false); } - void TearDown() override { MetadataBuilder::OverrideABForTesting(false); } + void SetUp() override { + MetadataBuilder::OverrideABForTesting(false); + MetadataBuilder::OverrideRetrofitDynamicParititonsForTesting(false); + } + void TearDown() override { + MetadataBuilder::OverrideABForTesting(false); + MetadataBuilder::OverrideRetrofitDynamicParititonsForTesting(false); + } }; TEST_F(BuilderTest, BuildBasic) { diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h index e70c55258..a2221ef5c 100644 --- a/fs_mgr/liblp/include/liblp/builder.h +++ b/fs_mgr/liblp/include/liblp/builder.h @@ -199,6 +199,9 @@ class MetadataBuilder { // Used by the test harness to override whether the device is "A/B". static void OverrideABForTesting(bool ab_device); + // Used by the test harness to override whether the device is "retrofitting dynamic partitions". + static void OverrideRetrofitDynamicParititonsForTesting(bool retrofit); + // Define a new partition group. By default there is one group called // "default", with an unrestricted size. A non-zero size will restrict the // total space used by all partitions in the group. @@ -306,8 +309,16 @@ class MetadataBuilder { void ImportExtents(Partition* dest, const LpMetadata& metadata, const LpMetadataPartition& source); bool ImportPartition(const LpMetadata& metadata, const LpMetadataPartition& source); - bool IsABDevice() const; - bool IsRetrofitDevice() const; + + // Return true if the device is an AB device. + static bool IsABDevice(); + + // Return true if the device is retrofitting dynamic partitions. + static bool IsRetrofitDynamicPartitionsDevice(); + + // Return true if "this" metadata represents a metadata on a retrofit device. + bool IsRetrofitMetadata() const; + bool ValidatePartitionGroups() const; struct Interval { @@ -336,8 +347,8 @@ class MetadataBuilder { const std::vector& free_list, uint64_t sectors_needed) const; - static bool sABOverrideValue; - static bool sABOverrideSet; + static std::optional sABOverride; + static std::optional sRetrofitDap; LpMetadataGeometry geometry_; LpMetadataHeader header_; diff --git a/fs_mgr/liblp/io_test.cpp b/fs_mgr/liblp/io_test.cpp index fcef1f0d0..70dd85f90 100644 --- a/fs_mgr/liblp/io_test.cpp +++ b/fs_mgr/liblp/io_test.cpp @@ -664,6 +664,8 @@ TEST(liblp, AutoSlotSuffixing) { } TEST(liblp, UpdateRetrofit) { + MetadataBuilder::OverrideRetrofitDynamicParititonsForTesting(true); + unique_ptr builder = CreateDefaultBuilder(); ASSERT_NE(builder, nullptr); ASSERT_TRUE(AddDefaultPartitions(builder.get())); @@ -693,6 +695,8 @@ TEST(liblp, UpdateRetrofit) { } TEST(liblp, UpdateNonRetrofit) { + MetadataBuilder::OverrideRetrofitDynamicParititonsForTesting(false); + unique_fd fd = CreateFlashedDisk(); ASSERT_GE(fd, 0);