Loading fs_mgr/libsnapshot/snapshot.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -1619,6 +1619,18 @@ bool SnapshotManager::RemoveAllSnapshots(LockedFile* lock) { // as dm-snapshot (for example, after merge completes). bool should_unmap = current_slot != Slot::Target; bool should_delete = ShouldDeleteSnapshot(flashing_status, current_slot, name); if (should_unmap && android::base::EndsWith(name, device_->GetSlotSuffix())) { // Something very unexpected has happened - we want to unmap this // snapshot, but it's on the wrong slot. We can't unmap an active // partition. If this is not really a snapshot, skip the unmap // step. auto& dm = DeviceMapper::Instance(); if (dm.GetState(name) == DmDeviceState::INVALID || !IsSnapshotDevice(name)) { LOG(ERROR) << "Detected snapshot " << name << " on " << current_slot << " slot" << " for source partition; removing without unmap."; should_unmap = false; } } bool partition_ok = true; if (should_unmap && !UnmapPartitionWithSnapshot(lock, name)) { Loading fs_mgr/libsnapshot/snapshot_test.cpp +28 −0 Original line number Diff line number Diff line Loading @@ -2021,6 +2021,34 @@ TEST_F(SnapshotUpdateTest, MapAllSnapshots) { ASSERT_TRUE(IsPartitionUnchanged("sys_b")); } TEST_F(SnapshotUpdateTest, CancelOnTargetSlot) { AddOperationForPartitions(); // Execute the update from B->A. test_device->set_slot_suffix("_b"); ASSERT_TRUE(sm->BeginUpdate()); ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_)); std::string path; ASSERT_TRUE(CreateLogicalPartition( CreateLogicalPartitionParams{ .block_device = fake_super, .metadata_slot = 0, .partition_name = "sys_a", .timeout_ms = 1s, .partition_opener = opener_.get(), }, &path)); // Hold sys_a open so it can't be unmapped. unique_fd fd(open(path.c_str(), O_RDONLY)); // Switch back to "A", make sure we can cancel. Instead of unmapping sys_a // we should simply delete the old snapshots. test_device->set_slot_suffix("_a"); ASSERT_TRUE(sm->BeginUpdate()); } class FlashAfterUpdateTest : public SnapshotUpdateTest, public WithParamInterface<std::tuple<uint32_t, bool>> { public: Loading Loading
fs_mgr/libsnapshot/snapshot.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -1619,6 +1619,18 @@ bool SnapshotManager::RemoveAllSnapshots(LockedFile* lock) { // as dm-snapshot (for example, after merge completes). bool should_unmap = current_slot != Slot::Target; bool should_delete = ShouldDeleteSnapshot(flashing_status, current_slot, name); if (should_unmap && android::base::EndsWith(name, device_->GetSlotSuffix())) { // Something very unexpected has happened - we want to unmap this // snapshot, but it's on the wrong slot. We can't unmap an active // partition. If this is not really a snapshot, skip the unmap // step. auto& dm = DeviceMapper::Instance(); if (dm.GetState(name) == DmDeviceState::INVALID || !IsSnapshotDevice(name)) { LOG(ERROR) << "Detected snapshot " << name << " on " << current_slot << " slot" << " for source partition; removing without unmap."; should_unmap = false; } } bool partition_ok = true; if (should_unmap && !UnmapPartitionWithSnapshot(lock, name)) { Loading
fs_mgr/libsnapshot/snapshot_test.cpp +28 −0 Original line number Diff line number Diff line Loading @@ -2021,6 +2021,34 @@ TEST_F(SnapshotUpdateTest, MapAllSnapshots) { ASSERT_TRUE(IsPartitionUnchanged("sys_b")); } TEST_F(SnapshotUpdateTest, CancelOnTargetSlot) { AddOperationForPartitions(); // Execute the update from B->A. test_device->set_slot_suffix("_b"); ASSERT_TRUE(sm->BeginUpdate()); ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_)); std::string path; ASSERT_TRUE(CreateLogicalPartition( CreateLogicalPartitionParams{ .block_device = fake_super, .metadata_slot = 0, .partition_name = "sys_a", .timeout_ms = 1s, .partition_opener = opener_.get(), }, &path)); // Hold sys_a open so it can't be unmapped. unique_fd fd(open(path.c_str(), O_RDONLY)); // Switch back to "A", make sure we can cancel. Instead of unmapping sys_a // we should simply delete the old snapshots. test_device->set_slot_suffix("_a"); ASSERT_TRUE(sm->BeginUpdate()); } class FlashAfterUpdateTest : public SnapshotUpdateTest, public WithParamInterface<std::tuple<uint32_t, bool>> { public: Loading