diff options
| author | Yifan Hong <elsk@google.com> | 2019-04-01 18:30:11 -0700 |
|---|---|---|
| committer | android-build-merger <android-build-merger@google.com> | 2019-04-01 18:30:11 -0700 |
| commit | 3745d713d03a68dfc3e71cd6b6bd720888bbeb64 (patch) | |
| tree | 4b16fb22d6d7b870947dd9226cdba923fd8af2c7 | |
| parent | 67adf624a772c5023d52bb3c95e40be9e68e6790 (diff) | |
| parent | acb1c0506e04511aa0b6a681efc8bf3e49ebbd9a (diff) | |
Fix resuming updates on DAP launch devices. am: 8546a717e5 am: 3af8947d54
am: acb1c0506e
Change-Id: Ie0c3e519410fdcba4f87fb251cfcec7d236bf87f
| -rw-r--r-- | boot_control_android.cc | 46 | ||||
| -rw-r--r-- | boot_control_android_unittest.cc | 13 | ||||
| -rw-r--r-- | dynamic_partition_control_android.cc | 47 | ||||
| -rw-r--r-- | dynamic_partition_control_android.h | 5 |
4 files changed, 81 insertions, 30 deletions
diff --git a/boot_control_android.cc b/boot_control_android.cc index 8909cd90..1fab85f1 100644 --- a/boot_control_android.cc +++ b/boot_control_android.cc @@ -135,11 +135,11 @@ BootControlAndroid::GetDynamicPartitionDevice( return DynamicPartitionDeviceStatus::ERROR; } + Slot current_slot = GetCurrentSlot(); if (builder->FindPartition(partition_name_suffix) == nullptr) { LOG(INFO) << partition_name_suffix << " is not in super partition metadata."; - Slot current_slot = GetCurrentSlot(); if (IsSuperBlockDevice(device_dir, current_slot, partition_name_suffix)) { LOG(ERROR) << "The static partition " << partition_name_suffix << " is a block device for current metadata (" @@ -152,36 +152,28 @@ BootControlAndroid::GetDynamicPartitionDevice( return DynamicPartitionDeviceStatus::TRY_STATIC; } - DmDeviceState state = dynamic_control_->GetState(partition_name_suffix); - - // Device is mapped in the previous GetPartitionDevice() call. Just return - // the path. - if (state == DmDeviceState::ACTIVE) { - if (dynamic_control_->GetDmDevicePathByName(partition_name_suffix, - device)) { - LOG(INFO) << partition_name_suffix - << " is mapped on device mapper: " << *device; - return DynamicPartitionDeviceStatus::SUCCESS; + if (slot == current_slot) { + if (dynamic_control_->GetState(partition_name_suffix) != + DmDeviceState::ACTIVE) { + LOG(WARNING) << partition_name_suffix << " is at current slot but it is " + << "not mapped. Now try to map it."; + } else { + if (dynamic_control_->GetDmDevicePathByName(partition_name_suffix, + device)) { + LOG(INFO) << partition_name_suffix + << " is mapped on device mapper: " << *device; + return DynamicPartitionDeviceStatus::SUCCESS; + } + LOG(ERROR) << partition_name_suffix << "is mapped but path is unknown."; + return DynamicPartitionDeviceStatus::ERROR; } - LOG(ERROR) << partition_name_suffix << " is mapped but path is unknown."; - return DynamicPartitionDeviceStatus::ERROR; } - if (state == DmDeviceState::INVALID) { - bool force_writable = slot != GetCurrentSlot(); - if (dynamic_control_->MapPartitionOnDeviceMapper(super_device, - partition_name_suffix, - slot, - force_writable, - device)) { - return DynamicPartitionDeviceStatus::SUCCESS; - } - return DynamicPartitionDeviceStatus::ERROR; + bool force_writable = slot != current_slot; + if (dynamic_control_->MapPartitionOnDeviceMapper( + super_device, partition_name_suffix, slot, force_writable, device)) { + return DynamicPartitionDeviceStatus::SUCCESS; } - - LOG(ERROR) << partition_name_suffix - << " is mapped on device mapper but state is unknown: " - << static_cast<std::underlying_type_t<DmDeviceState>>(state); return DynamicPartitionDeviceStatus::ERROR; } diff --git a/boot_control_android_unittest.cc b/boot_control_android_unittest.cc index bb9903e2..b2885a3f 100644 --- a/boot_control_android_unittest.cc +++ b/boot_control_android_unittest.cc @@ -593,10 +593,19 @@ TEST_P(BootControlAndroidTestP, GetPartitionDeviceWhenResumingUpdate) { 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); diff --git a/dynamic_partition_control_android.cc b/dynamic_partition_control_android.cc index bd34ea91..40c26637 100644 --- a/dynamic_partition_control_android.cc +++ b/dynamic_partition_control_android.cc @@ -58,7 +58,7 @@ bool DynamicPartitionControlAndroid::IsDynamicPartitionsRetrofit() { return GetBoolProperty(kRetrfoitDynamicPartitions, false); } -bool DynamicPartitionControlAndroid::MapPartitionOnDeviceMapper( +bool DynamicPartitionControlAndroid::MapPartitionInternal( const std::string& super_device, const std::string& target_partition_name, uint32_t slot, @@ -81,6 +81,51 @@ bool DynamicPartitionControlAndroid::MapPartitionOnDeviceMapper( return true; } +bool DynamicPartitionControlAndroid::MapPartitionOnDeviceMapper( + const std::string& super_device, + const std::string& target_partition_name, + uint32_t slot, + bool force_writable, + std::string* path) { + DmDeviceState state = GetState(target_partition_name); + if (state == DmDeviceState::ACTIVE) { + if (mapped_devices_.find(target_partition_name) != mapped_devices_.end()) { + if (GetDmDevicePathByName(target_partition_name, path)) { + LOG(INFO) << target_partition_name + << " is mapped on device mapper: " << *path; + return true; + } + LOG(ERROR) << target_partition_name << " is mapped but path is unknown."; + return false; + } + // If target_partition_name is not in mapped_devices_ but state is ACTIVE, + // the device might be mapped incorrectly before. Attempt to unmap it. + // Note that for source partitions, if GetState() == ACTIVE, callers (e.g. + // BootControlAndroid) should not call MapPartitionOnDeviceMapper, but + // should directly call GetDmDevicePathByName. + if (!UnmapPartitionOnDeviceMapper(target_partition_name, true /* wait */)) { + LOG(ERROR) << target_partition_name + << " is mapped before the update, and it cannot be unmapped."; + return false; + } + state = GetState(target_partition_name); + if (state != DmDeviceState::INVALID) { + LOG(ERROR) << target_partition_name << " is unmapped but state is " + << static_cast<std::underlying_type_t<DmDeviceState>>(state); + return false; + } + } + if (state == DmDeviceState::INVALID) { + return MapPartitionInternal( + super_device, target_partition_name, slot, force_writable, path); + } + + LOG(ERROR) << target_partition_name + << " is mapped on device mapper but state is unknown: " + << static_cast<std::underlying_type_t<DmDeviceState>>(state); + return false; +} + bool DynamicPartitionControlAndroid::UnmapPartitionOnDeviceMapper( const std::string& target_partition_name, bool wait) { if (DeviceMapper::Instance().GetState(target_partition_name) != diff --git a/dynamic_partition_control_android.h b/dynamic_partition_control_android.h index 0ccab4ef..1233b642 100644 --- a/dynamic_partition_control_android.h +++ b/dynamic_partition_control_android.h @@ -56,6 +56,11 @@ class DynamicPartitionControlAndroid : public DynamicPartitionControlInterface { std::set<std::string> mapped_devices_; void CleanupInternal(bool wait); + bool MapPartitionInternal(const std::string& super_device, + const std::string& target_partition_name, + uint32_t slot, + bool force_writable, + std::string* path); DISALLOW_COPY_AND_ASSIGN(DynamicPartitionControlAndroid); }; |
