Merge "libsnapshot: Remove all image data and metadata when cancelling an update." am: 710d6cc419
am: 332360fece
Change-Id: Id4150ea2cce64491c3ee08cf262f59476d197ae6
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index 5573abc..33c122b 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -129,6 +129,11 @@
auto file = LockExclusive();
if (!file) return false;
+ // Purge the ImageManager just in case there is a corrupt lp_metadata file
+ // lying around. (NB: no need to return false on an error, we can let the
+ // update try to progress.)
+ images_->RemoveAllImages();
+
auto state = ReadUpdateState(file.get());
if (state != UpdateState::None) {
LOG(ERROR) << "An update is already in progress, cannot begin a new update";
@@ -1182,8 +1187,26 @@
}
bool ok = true;
+ bool has_mapped_cow_images = false;
for (const auto& name : snapshots) {
- ok &= (UnmapPartitionWithSnapshot(lock, name) && DeleteSnapshot(lock, name));
+ if (!UnmapPartitionWithSnapshot(lock, name) || !DeleteSnapshot(lock, name)) {
+ // Remember whether or not we were able to unmap the cow image.
+ auto cow_image_device = GetCowImageDeviceName(name);
+ has_mapped_cow_images |= images_->IsImageMapped(cow_image_device);
+
+ ok = false;
+ }
+ }
+
+ if (ok || !has_mapped_cow_images) {
+ // Delete any image artifacts as a precaution, in case an update is
+ // being cancelled due to some corrupted state in an lp_metadata file.
+ // Note that we do not do this if some cow images are still mapped,
+ // since we must not remove backing storage if it's in use.
+ if (!images_->RemoveAllImages()) {
+ LOG(ERROR) << "Could not remove all snapshot artifacts";
+ return false;
+ }
}
return ok;
}