diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h index 71cdbe03b..397ff2e7d 100644 --- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h +++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h @@ -630,6 +630,9 @@ class SnapshotManager final : public ISnapshotManager { // The reverse of MapPartitionWithSnapshot. bool UnmapPartitionWithSnapshot(LockedFile* lock, const std::string& target_partition_name); + // Unmap a dm-user device through snapuserd. + bool UnmapDmUserDevice(const std::string& snapshot_name); + // If there isn't a previous update, return true. |needs_merge| is set to false. // If there is a previous update but the device has not boot into it, tries to cancel the // update and delete any snapshots. Return true if successful. |needs_merge| is set to false. diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp index 67b5b8b0e..f0646fcfb 100644 --- a/fs_mgr/libsnapshot/snapshot.cpp +++ b/fs_mgr/libsnapshot/snapshot.cpp @@ -1247,6 +1247,10 @@ bool SnapshotManager::CollapseSnapshotDevice(const std::string& name, return false; } + if (status.compression_enabled()) { + UnmapDmUserDevice(name); + } + // Cleanup the base device as well, since it is no longer used. This does // not block cleanup. auto base_name = GetBaseDeviceName(name); @@ -2063,27 +2067,8 @@ bool SnapshotManager::UnmapCowDevices(LockedFile* lock, const std::string& name) auto& dm = DeviceMapper::Instance(); - auto dm_user_name = GetDmUserCowName(name); - if (IsCompressionEnabled() && dm.GetState(dm_user_name) != DmDeviceState::INVALID) { - if (!EnsureSnapuserdConnected()) { - return false; - } - if (!dm.DeleteDeviceIfExists(dm_user_name)) { - LOG(ERROR) << "Cannot unmap " << dm_user_name; - return false; - } - - if (!snapuserd_client_->WaitForDeviceDelete(dm_user_name)) { - LOG(ERROR) << "Failed to wait for " << dm_user_name << " control device to delete"; - return false; - } - - // Ensure the control device is gone so we don't run into ABA problems. - auto control_device = "/dev/dm-user/" + dm_user_name; - if (!android::fs_mgr::WaitForFileDeleted(control_device, 10s)) { - LOG(ERROR) << "Timed out waiting for " << control_device << " to unlink"; - return false; - } + if (IsCompressionEnabled() && !UnmapDmUserDevice(name)) { + return false; } auto cow_name = GetCowName(name); @@ -2100,6 +2085,37 @@ bool SnapshotManager::UnmapCowDevices(LockedFile* lock, const std::string& name) return true; } +bool SnapshotManager::UnmapDmUserDevice(const std::string& snapshot_name) { + auto& dm = DeviceMapper::Instance(); + + if (!EnsureSnapuserdConnected()) { + return false; + } + + auto dm_user_name = GetDmUserCowName(snapshot_name); + if (dm.GetState(dm_user_name) == DmDeviceState::INVALID) { + return true; + } + + if (!dm.DeleteDeviceIfExists(dm_user_name)) { + LOG(ERROR) << "Cannot unmap " << dm_user_name; + return false; + } + + if (!snapuserd_client_->WaitForDeviceDelete(dm_user_name)) { + LOG(ERROR) << "Failed to wait for " << dm_user_name << " control device to delete"; + return false; + } + + // Ensure the control device is gone so we don't run into ABA problems. + auto control_device = "/dev/dm-user/" + dm_user_name; + if (!android::fs_mgr::WaitForFileDeleted(control_device, 10s)) { + LOG(ERROR) << "Timed out waiting for " << control_device << " to unlink"; + return false; + } + return true; +} + bool SnapshotManager::MapAllSnapshots(const std::chrono::milliseconds& timeout_ms) { auto lock = LockExclusive(); if (!lock) return false;