Fix resuming updates on DAP launch devices.
On devices that launch with dynamic partitions, the following
sequence may occur:
- update started (assume current_slot = A)
- super partition metadata slot B initialized
- device rebooted
- init maps system_b from extents in metadata slot A
- update is resumed, but system_b has wrong extents now
InitPartitionMetadata is not called when update is resumed, hence
system_b is not unmapped before GetDynamicPartitionDevice is called.
The new logic for GetDynamicPartitionDevice is as follows:
if (slot == current_slot && partition is mapped) {
return GetDmDevicePathByName
}
return MapPartitionOnDeviceMapper
The new logic for MapPartitionOnDeviceMapper is as follows:
if (not mapped) return CreateLogicalPartition;
if (mapped) {
if (mapped by update_engine) {
return GetDmDevicePathByName;
}
DestroyLogicalPartition;
return CreateLogicalPartition;
}
Test: start OTA, see partition metadata initialized, reboot
and resume OTA
Test: update_engine_unittests
Fixes: 129292271
Change-Id: If0b541e9aa42a7f462c1061c67750cf360e42732
diff --git a/boot_control_android_unittest.cc b/boot_control_android_unittest.cc
index bb9903e..b2885a3 100644
--- a/boot_control_android_unittest.cc
+++ b/boot_control_android_unittest.cc
@@ -593,10 +593,19 @@
EXPECT_EQ(GetDmDevice(S("system")), system_device);
EXPECT_CALL(dynamicControl(), GetState(T("system")))
- .Times(1)
+ .Times(AnyNumber())
.WillOnce(Return(DmDeviceState::ACTIVE));
+ EXPECT_CALL(dynamicControl(),
+ MapPartitionOnDeviceMapper(
+ GetSuperDevice(target()), T("system"), target(), _, _))
+ .Times(AnyNumber())
+ .WillRepeatedly(
+ Invoke([](const auto&, const auto& name, auto, auto, auto* device) {
+ *device = "/fake/remapped/" + name;
+ return true;
+ }));
EXPECT_TRUE(bootctl_.GetPartitionDevice("system", target(), &system_device));
- EXPECT_EQ(GetDmDevice(T("system")), system_device);
+ EXPECT_EQ("/fake/remapped/" + T("system"), system_device);
// Static partition "bar".
EXPECT_CALL(dynamicControl(), GetState(S("bar"))).Times(0);