Call InitPartitionMetadata when resuming an update.
am: 3406c772a3
Change-Id: I21a233e57d383f7ceb6f9923b647d634467b6210
diff --git a/boot_control_android.cc b/boot_control_android.cc
index af1a5f9..421c091 100644
--- a/boot_control_android.cc
+++ b/boot_control_android.cc
@@ -396,7 +396,9 @@
} // namespace
bool BootControlAndroid::InitPartitionMetadata(
- Slot target_slot, const PartitionMetadata& partition_metadata) {
+ Slot target_slot,
+ const PartitionMetadata& partition_metadata,
+ bool update_metadata) {
if (fs_mgr_overlayfs_is_setup()) {
// Non DAP devices can use overlayfs as well.
LOG(WARNING)
@@ -414,11 +416,6 @@
return false;
}
- string target_suffix;
- if (!GetSuffix(target_slot, &target_suffix)) {
- return false;
- }
-
// Although the current build supports dynamic partitions, the given payload
// doesn't use it for target partitions. This could happen when applying a
// retrofit update. Skip updating the partition metadata for the target slot.
@@ -427,6 +424,15 @@
return true;
}
+ if (!update_metadata) {
+ return true;
+ }
+
+ string target_suffix;
+ if (!GetSuffix(target_slot, &target_suffix)) {
+ return false;
+ }
+
// Unmap all the target dynamic partitions because they would become
// inconsistent with the new metadata.
if (!UnmapTargetPartitions(
@@ -434,15 +440,11 @@
return false;
}
- if (!UpdatePartitionMetadata(dynamic_control_.get(),
- source_slot,
- target_slot,
- target_suffix,
- partition_metadata)) {
- return false;
- }
-
- return true;
+ return UpdatePartitionMetadata(dynamic_control_.get(),
+ source_slot,
+ target_slot,
+ target_suffix,
+ partition_metadata);
}
} // namespace chromeos_update_engine
diff --git a/boot_control_android.h b/boot_control_android.h
index aa62e42..a6f33be 100644
--- a/boot_control_android.h
+++ b/boot_control_android.h
@@ -51,8 +51,9 @@
bool MarkSlotUnbootable(BootControlInterface::Slot slot) override;
bool SetActiveBootSlot(BootControlInterface::Slot slot) override;
bool MarkBootSuccessfulAsync(base::Callback<void(bool)> callback) override;
- bool InitPartitionMetadata(
- Slot slot, const PartitionMetadata& partition_metadata) override;
+ bool InitPartitionMetadata(Slot slot,
+ const PartitionMetadata& partition_metadata,
+ bool update_metadata) override;
void Cleanup() override;
private:
diff --git a/boot_control_android_unittest.cc b/boot_control_android_unittest.cc
index 0eb3fe0..bb9903e 100644
--- a/boot_control_android_unittest.cc
+++ b/boot_control_android_unittest.cc
@@ -379,10 +379,12 @@
.Times(0);
}
- bool InitPartitionMetadata(uint32_t slot, PartitionSizes partition_sizes) {
+ bool InitPartitionMetadata(uint32_t slot,
+ PartitionSizes partition_sizes,
+ bool update_metadata = true) {
auto m = partitionSizesToMetadata(partition_sizes);
LOG(INFO) << m;
- return bootctl_.InitPartitionMetadata(slot, m);
+ return bootctl_.InitPartitionMetadata(slot, m, update_metadata);
}
BootControlAndroid bootctl_; // BootControlAndroid under test.
@@ -537,21 +539,74 @@
// Not calling through BootControlAndroidTest::InitPartitionMetadata(), since
// we don't want any default group in the PartitionMetadata.
- EXPECT_TRUE(bootctl_.InitPartitionMetadata(target(), {}));
+ EXPECT_TRUE(bootctl_.InitPartitionMetadata(target(), {}, true));
// Should use dynamic source partitions.
EXPECT_CALL(dynamicControl(), GetState(S("system")))
.Times(1)
.WillOnce(Return(DmDeviceState::ACTIVE));
- string source_device;
- EXPECT_TRUE(bootctl_.GetPartitionDevice("system", source(), &source_device));
- EXPECT_EQ(GetDmDevice(S("system")), source_device);
+ string system_device;
+ EXPECT_TRUE(bootctl_.GetPartitionDevice("system", source(), &system_device));
+ EXPECT_EQ(GetDmDevice(S("system")), system_device);
// Should use static target partitions without querying dynamic control.
EXPECT_CALL(dynamicControl(), GetState(T("system"))).Times(0);
- string target_device;
- EXPECT_TRUE(bootctl_.GetPartitionDevice("system", target(), &target_device));
- EXPECT_EQ(GetDevice(T("system")), target_device);
+ EXPECT_TRUE(bootctl_.GetPartitionDevice("system", target(), &system_device));
+ EXPECT_EQ(GetDevice(T("system")), system_device);
+
+ // Static partition "bar".
+ EXPECT_CALL(dynamicControl(), GetState(S("bar"))).Times(0);
+ std::string bar_device;
+ EXPECT_TRUE(bootctl_.GetPartitionDevice("bar", source(), &bar_device));
+ EXPECT_EQ(GetDevice(S("bar")), bar_device);
+
+ EXPECT_CALL(dynamicControl(), GetState(T("bar"))).Times(0);
+ EXPECT_TRUE(bootctl_.GetPartitionDevice("bar", target(), &bar_device));
+ EXPECT_EQ(GetDevice(T("bar")), bar_device);
+}
+
+TEST_P(BootControlAndroidTestP, GetPartitionDeviceWhenResumingUpdate) {
+ // Both of the two slots contain valid partition metadata, since this is
+ // resuming an update.
+ SetMetadata(source(),
+ {{S("system"), 2_GiB},
+ {S("vendor"), 1_GiB},
+ {T("system"), 2_GiB},
+ {T("vendor"), 1_GiB}});
+ SetMetadata(target(),
+ {{S("system"), 2_GiB},
+ {S("vendor"), 1_GiB},
+ {T("system"), 2_GiB},
+ {T("vendor"), 1_GiB}});
+ EXPECT_CALL(dynamicControl(),
+ StoreMetadata(GetSuperDevice(target()), _, target()))
+ .Times(0);
+ EXPECT_TRUE(InitPartitionMetadata(
+ target(), {{"system", 2_GiB}, {"vendor", 1_GiB}}, false));
+
+ // Dynamic partition "system".
+ EXPECT_CALL(dynamicControl(), GetState(S("system")))
+ .Times(1)
+ .WillOnce(Return(DmDeviceState::ACTIVE));
+ string system_device;
+ EXPECT_TRUE(bootctl_.GetPartitionDevice("system", source(), &system_device));
+ EXPECT_EQ(GetDmDevice(S("system")), system_device);
+
+ EXPECT_CALL(dynamicControl(), GetState(T("system")))
+ .Times(1)
+ .WillOnce(Return(DmDeviceState::ACTIVE));
+ EXPECT_TRUE(bootctl_.GetPartitionDevice("system", target(), &system_device));
+ EXPECT_EQ(GetDmDevice(T("system")), system_device);
+
+ // Static partition "bar".
+ EXPECT_CALL(dynamicControl(), GetState(S("bar"))).Times(0);
+ std::string bar_device;
+ EXPECT_TRUE(bootctl_.GetPartitionDevice("bar", source(), &bar_device));
+ EXPECT_EQ(GetDevice(S("bar")), bar_device);
+
+ EXPECT_CALL(dynamicControl(), GetState(T("bar"))).Times(0);
+ EXPECT_TRUE(bootctl_.GetPartitionDevice("bar", target(), &bar_device));
+ EXPECT_EQ(GetDevice(T("bar")), bar_device);
}
INSTANTIATE_TEST_CASE_P(BootControlAndroidTest,
@@ -695,7 +750,8 @@
target(),
PartitionMetadata{
.groups = {SimpleGroup("android", 3_GiB, "system", 3_GiB),
- SimpleGroup("oem", 2_GiB, "vendor", 2_GiB)}}));
+ SimpleGroup("oem", 2_GiB, "vendor", 2_GiB)}},
+ true));
}
TEST_P(BootControlAndroidGroupTestP, NotEnoughSpaceForGroup) {
@@ -703,7 +759,8 @@
target(),
PartitionMetadata{
.groups = {SimpleGroup("android", 3_GiB, "system", 1_GiB),
- SimpleGroup("oem", 2_GiB, "vendor", 3_GiB)}}))
+ SimpleGroup("oem", 2_GiB, "vendor", 3_GiB)}},
+ true))
<< "Should not be able to grow over maximum size of group";
}
@@ -711,7 +768,8 @@
EXPECT_FALSE(bootctl_.InitPartitionMetadata(
target(),
PartitionMetadata{.groups = {{.name = "android", .size = 3_GiB},
- {.name = "oem", .size = 3_GiB}}}))
+ {.name = "oem", .size = 3_GiB}}},
+ true))
<< "Should not be able to grow over size of super / 2";
}
@@ -727,12 +785,13 @@
EXPECT_TRUE(bootctl_.InitPartitionMetadata(
target(),
PartitionMetadata{
- .groups = {
- {.name = "android",
- .size = 3_GiB,
- .partitions = {{.name = "system", .size = 2_GiB},
- {.name = "product_services", .size = 1_GiB}}},
- SimpleGroup("oem", 2_GiB, "vendor", 2_GiB)}}));
+ .groups = {{.name = "android",
+ .size = 3_GiB,
+ .partitions = {{.name = "system", .size = 2_GiB},
+ {.name = "product_services",
+ .size = 1_GiB}}},
+ SimpleGroup("oem", 2_GiB, "vendor", 2_GiB)}},
+ true));
}
TEST_P(BootControlAndroidGroupTestP, RemovePartitionFromGroup) {
@@ -744,7 +803,8 @@
target(),
PartitionMetadata{
.groups = {{.name = "android", .size = 3_GiB, .partitions = {}},
- SimpleGroup("oem", 2_GiB, "vendor", 2_GiB)}}));
+ SimpleGroup("oem", 2_GiB, "vendor", 2_GiB)}},
+ true));
}
TEST_P(BootControlAndroidGroupTestP, AddGroup) {
@@ -756,10 +816,10 @@
EXPECT_TRUE(bootctl_.InitPartitionMetadata(
target(),
PartitionMetadata{
- .groups = {
- SimpleGroup("android", 2_GiB, "system", 2_GiB),
- SimpleGroup("oem", 1_GiB, "vendor", 1_GiB),
- SimpleGroup("new_group", 2_GiB, "new_partition", 2_GiB)}}));
+ .groups = {SimpleGroup("android", 2_GiB, "system", 2_GiB),
+ SimpleGroup("oem", 1_GiB, "vendor", 1_GiB),
+ SimpleGroup("new_group", 2_GiB, "new_partition", 2_GiB)}},
+ true));
}
TEST_P(BootControlAndroidGroupTestP, RemoveGroup) {
@@ -768,7 +828,8 @@
EXPECT_TRUE(bootctl_.InitPartitionMetadata(
target(),
PartitionMetadata{
- .groups = {SimpleGroup("android", 2_GiB, "system", 2_GiB)}}));
+ .groups = {SimpleGroup("android", 2_GiB, "system", 2_GiB)}},
+ true));
}
TEST_P(BootControlAndroidGroupTestP, ResizeGroup) {
@@ -781,7 +842,8 @@
target(),
PartitionMetadata{
.groups = {SimpleGroup("android", 2_GiB, "system", 2_GiB),
- SimpleGroup("oem", 3_GiB, "vendor", 3_GiB)}}));
+ SimpleGroup("oem", 3_GiB, "vendor", 3_GiB)}},
+ true));
}
INSTANTIATE_TEST_CASE_P(BootControlAndroidTest,
diff --git a/boot_control_chromeos.cc b/boot_control_chromeos.cc
index a82efc7..4fa1268 100644
--- a/boot_control_chromeos.cc
+++ b/boot_control_chromeos.cc
@@ -303,7 +303,9 @@
}
bool BootControlChromeOS::InitPartitionMetadata(
- Slot slot, const PartitionMetadata& partition_metadata) {
+ Slot slot,
+ const PartitionMetadata& partition_metadata,
+ bool update_metadata) {
return true;
}
diff --git a/boot_control_chromeos.h b/boot_control_chromeos.h
index c474d6f..f3682e9 100644
--- a/boot_control_chromeos.h
+++ b/boot_control_chromeos.h
@@ -50,8 +50,9 @@
bool MarkSlotUnbootable(BootControlInterface::Slot slot) override;
bool SetActiveBootSlot(BootControlInterface::Slot slot) override;
bool MarkBootSuccessfulAsync(base::Callback<void(bool)> callback) override;
- bool InitPartitionMetadata(
- Slot slot, const PartitionMetadata& partition_metadata) override;
+ bool InitPartitionMetadata(Slot slot,
+ const PartitionMetadata& partition_metadata,
+ bool update_metadata) override;
void Cleanup() override;
private:
diff --git a/common/boot_control_interface.h b/common/boot_control_interface.h
index 43517ce..392d785 100644
--- a/common/boot_control_interface.h
+++ b/common/boot_control_interface.h
@@ -66,7 +66,9 @@
// Determines the block device for the given partition name and slot number.
// The |slot| number must be between 0 and GetNumSlots() - 1 and the
// |partition_name| is a platform-specific name that identifies a partition on
- // every slot. On success, returns true and stores the block device in
+ // every slot. In order to access the dynamic partitions in the target slot,
+ // InitPartitionMetadata() must be called (once per payload) prior to calling
+ // this function. On success, returns true and stores the block device in
// |device|.
virtual bool GetPartitionDevice(const std::string& partition_name,
Slot slot,
@@ -92,14 +94,14 @@
// of the operation.
virtual bool MarkBootSuccessfulAsync(base::Callback<void(bool)> callback) = 0;
- // Initialize metadata of underlying partitions for a given |slot|.
- // Ensure that all updateable groups with the suffix GetSuffix(|slot|) exactly
- // matches the layout specified in |partition_metadata|. Ensure that
- // partitions at the specified |slot| has a given size and updateable group,
- // as specified by |partition_metadata|. Sizes must be aligned to the logical
- // block size of the super partition.
+ // Initializes the metadata of the underlying partitions for a given |slot|
+ // and sets up the states for accessing dynamic partitions.
+ // |partition_metadata| will be written to the specified |slot| if
+ // |update_metadata| is set.
virtual bool InitPartitionMetadata(
- Slot slot, const PartitionMetadata& partition_metadata) = 0;
+ Slot slot,
+ const PartitionMetadata& partition_metadata,
+ bool update_metadata) = 0;
// Do necessary clean-up operations after the whole update.
virtual void Cleanup() = 0;
diff --git a/common/boot_control_stub.cc b/common/boot_control_stub.cc
index ca880d4..0fe8a98 100644
--- a/common/boot_control_stub.cc
+++ b/common/boot_control_stub.cc
@@ -60,7 +60,9 @@
}
bool BootControlStub::InitPartitionMetadata(
- Slot slot, const PartitionMetadata& partition_metadata) {
+ Slot slot,
+ const PartitionMetadata& partition_metadata,
+ bool update_metadata) {
LOG(ERROR) << __FUNCTION__ << " should never be called.";
return false;
}
diff --git a/common/boot_control_stub.h b/common/boot_control_stub.h
index 0950997..8dfaffc 100644
--- a/common/boot_control_stub.h
+++ b/common/boot_control_stub.h
@@ -45,8 +45,9 @@
bool MarkSlotUnbootable(BootControlInterface::Slot slot) override;
bool SetActiveBootSlot(BootControlInterface::Slot slot) override;
bool MarkBootSuccessfulAsync(base::Callback<void(bool)> callback) override;
- bool InitPartitionMetadata(
- Slot slot, const PartitionMetadata& partition_metadata) override;
+ bool InitPartitionMetadata(Slot slot,
+ const PartitionMetadata& partition_metadata,
+ bool update_metadata) override;
void Cleanup() override;
private:
diff --git a/common/constants.cc b/common/constants.cc
index 3ae7a60..310f1b2 100644
--- a/common/constants.cc
+++ b/common/constants.cc
@@ -37,8 +37,8 @@
const char kPrefsDailyMetricsLastReportedAt[] =
"daily-metrics-last-reported-at";
const char kPrefsDeltaUpdateFailures[] = "delta-update-failures";
-const char kPrefsDynamicPartitionMetadataInitialized[] =
- "dynamic-partition-metadata-initialized";
+const char kPrefsDynamicPartitionMetadataUpdated[] =
+ "dynamic-partition-metadata-updated";
const char kPrefsFullPayloadAttemptNumber[] = "full-payload-attempt-number";
const char kPrefsInstallDateDays[] = "install-date-days";
const char kPrefsLastActivePingDay[] = "last-active-ping-day";
diff --git a/common/constants.h b/common/constants.h
index 61e5ddd..d5a8ae3 100644
--- a/common/constants.h
+++ b/common/constants.h
@@ -41,7 +41,7 @@
extern const char kPrefsCurrentUrlIndex[];
extern const char kPrefsDailyMetricsLastReportedAt[];
extern const char kPrefsDeltaUpdateFailures[];
-extern const char kPrefsDynamicPartitionMetadataInitialized[];
+extern const char kPrefsDynamicPartitionMetadataUpdated[];
extern const char kPrefsFullPayloadAttemptNumber[];
extern const char kPrefsInstallDateDays[];
extern const char kPrefsLastActivePingDay[];
diff --git a/common/fake_boot_control.h b/common/fake_boot_control.h
index 513c149..ba975a2 100644
--- a/common/fake_boot_control.h
+++ b/common/fake_boot_control.h
@@ -74,8 +74,9 @@
return true;
}
- bool InitPartitionMetadata(
- Slot slot, const PartitionMetadata& partition_metadata) override {
+ bool InitPartitionMetadata(Slot slot,
+ const PartitionMetadata& partition_metadata,
+ bool update_metadata) override {
return true;
}
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index 0711ac6..1bfdf9c 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -935,14 +935,6 @@
}
bool DeltaPerformer::InitPartitionMetadata() {
- bool metadata_initialized;
- if (prefs_->GetBoolean(kPrefsDynamicPartitionMetadataInitialized,
- &metadata_initialized) &&
- metadata_initialized) {
- LOG(INFO) << "Skipping InitPartitionMetadata.";
- return true;
- }
-
BootControlInterface::PartitionMetadata partition_metadata;
if (manifest_.has_dynamic_partition_metadata()) {
std::map<string, uint64_t> partition_sizes;
@@ -970,14 +962,16 @@
}
}
- if (!boot_control_->InitPartitionMetadata(install_plan_->target_slot,
- partition_metadata)) {
+ bool metadata_updated = false;
+ prefs_->GetBoolean(kPrefsDynamicPartitionMetadataUpdated, &metadata_updated);
+ if (!boot_control_->InitPartitionMetadata(
+ install_plan_->target_slot, partition_metadata, !metadata_updated)) {
LOG(ERROR) << "Unable to initialize partition metadata for slot "
<< BootControlInterface::SlotName(install_plan_->target_slot);
return false;
}
TEST_AND_RETURN_FALSE(
- prefs_->SetBoolean(kPrefsDynamicPartitionMetadataInitialized, true));
+ prefs_->SetBoolean(kPrefsDynamicPartitionMetadataUpdated, true));
LOG(INFO) << "InitPartitionMetadata done.";
return true;
@@ -1901,7 +1895,7 @@
prefs->SetInt64(kPrefsResumedUpdateFailures, 0);
prefs->Delete(kPrefsPostInstallSucceeded);
prefs->Delete(kPrefsVerityWritten);
- prefs->Delete(kPrefsDynamicPartitionMetadataInitialized);
+ prefs->Delete(kPrefsDynamicPartitionMetadataUpdated);
}
return true;
}
diff --git a/payload_consumer/delta_performer_integration_test.cc b/payload_consumer/delta_performer_integration_test.cc
index 9368e11..0912764 100644
--- a/payload_consumer/delta_performer_integration_test.cc
+++ b/payload_consumer/delta_performer_integration_test.cc
@@ -697,7 +697,7 @@
.WillRepeatedly(Return(true));
EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignedSHA256Context, _))
.WillRepeatedly(Return(true));
- EXPECT_CALL(prefs, SetBoolean(kPrefsDynamicPartitionMetadataInitialized, _))
+ EXPECT_CALL(prefs, SetBoolean(kPrefsDynamicPartitionMetadataUpdated, _))
.WillRepeatedly(Return(true));
if (op_hash_test == kValidOperationData && signature_test != kSignatureNone) {
EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignatureBlob, _))