MetadataBuilder::NewForUpdate: check sysprop instead
Check the value of ro.boot.dynamic_partitions_retrofit instead of
checking the name of the super partition being 'super' is a more
reliable way of determining retrofit DAP devices.
Some devices launch with DAP (e.g. cuttlefish) doesn't have "super"
as the super partition name. When Virtual A/B is implemented on
cuttlefish, update_engine calls NewForUpdate for the current super
partition metadata. Hence, this code needs to check the retrofit
sysprop instead.
Also, renamed IsRetrofitDevice to IsRetrofitMetadata to avoid the
confusion.
Test: OTA on retrofit DAP device
Test: OTA on launch DAP device
Test: liblp_test_static
Change-Id: I4636de854734df1bb61779d9a955217e89fdb2fd
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index 25a042f..2a5af40 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -32,6 +32,7 @@
bool MetadataBuilder::sABOverrideSet;
bool MetadataBuilder::sABOverrideValue;
+std::optional<bool> MetadataBuilder::sRetrofitDap;
static const std::string kDefaultGroup = "default";
@@ -169,7 +170,8 @@
// 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);
}
@@ -214,6 +216,10 @@
sABOverrideValue = ab_device;
}
+void MetadataBuilder::OverrideRetrofitDynamicParititonsForTesting(bool retrofit) {
+ sRetrofitDap = retrofit;
+}
+
MetadataBuilder::MetadataBuilder() : auto_slot_suffixing_(false) {
memset(&geometry_, 0, sizeof(geometry_));
geometry_.magic = LP_METADATA_GEOMETRY_MAGIC;
@@ -580,7 +586,8 @@
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);
@@ -1051,7 +1058,14 @@
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 34c68d4..d35af04 100644
--- a/fs_mgr/liblp/builder_test.cpp
+++ b/fs_mgr/liblp/builder_test.cpp
@@ -27,7 +27,10 @@
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) {
@@ -39,8 +42,14 @@
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 e70c552..55d82b1 100644
--- a/fs_mgr/liblp/include/liblp/builder.h
+++ b/fs_mgr/liblp/include/liblp/builder.h
@@ -199,6 +199,9 @@
// 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.
@@ -307,7 +310,13 @@
const LpMetadataPartition& source);
bool ImportPartition(const LpMetadata& metadata, const LpMetadataPartition& source);
bool IsABDevice() const;
- bool IsRetrofitDevice() const;
+
+ // 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 {
@@ -338,6 +347,7 @@
static bool sABOverrideValue;
static bool sABOverrideSet;
+ static std::optional<bool> sRetrofitDap;
LpMetadataGeometry geometry_;
LpMetadataHeader header_;
diff --git a/fs_mgr/liblp/io_test.cpp b/fs_mgr/liblp/io_test.cpp
index fcef1f0..70dd85f 100644
--- a/fs_mgr/liblp/io_test.cpp
+++ b/fs_mgr/liblp/io_test.cpp
@@ -664,6 +664,8 @@
}
TEST(liblp, UpdateRetrofit) {
+ MetadataBuilder::OverrideRetrofitDynamicParititonsForTesting(true);
+
unique_ptr<MetadataBuilder> builder = CreateDefaultBuilder();
ASSERT_NE(builder, nullptr);
ASSERT_TRUE(AddDefaultPartitions(builder.get()));
@@ -693,6 +695,8 @@
}
TEST(liblp, UpdateNonRetrofit) {
+ MetadataBuilder::OverrideRetrofitDynamicParititonsForTesting(false);
+
unique_fd fd = CreateFlashedDisk();
ASSERT_GE(fd, 0);