libsnapshot_fuzzer: Properly unmap images

Instead of unsetting gsid.mapped_images.* directly, properly unmap
them through image manager. This also avoids interference between
different fuzzer runs because the gsid.mapped_images.* properties
are not destroyed in SoftReset.

Test: libsnapshot_fuzzer_test then reboot, device can come up
Fixes: 156689792
Bug: 156380383
Change-Id: I7a198312f63b4b17d8ea96c7df2dd112a910d004
diff --git a/fs_mgr/libsnapshot/snapshot_fuzz_utils.cpp b/fs_mgr/libsnapshot/snapshot_fuzz_utils.cpp
index c9f1ab0..8926535 100644
--- a/fs_mgr/libsnapshot/snapshot_fuzz_utils.cpp
+++ b/fs_mgr/libsnapshot/snapshot_fuzz_utils.cpp
@@ -27,7 +27,6 @@
 #include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
-#include <cutils/properties.h>
 #include <fs_mgr.h>
 #include <libsnapshot/auto_device.h>
 #include <libsnapshot/snapshot.h>
@@ -165,14 +164,6 @@
     reinterpret_cast<PropertyList*>(cookie)->insert(key);
 }
 
-void CheckUnsetGsidProps() {
-    PropertyList list;
-    property_list(&InsertProperty, reinterpret_cast<void*>(&list));
-    for (const auto& key : list) {
-        SetProperty(key, "");
-    }
-}
-
 // Attempt to delete all devices that is based on dev_name, including itself.
 void CheckDeleteDeviceMapperTree(const std::string& dev_name, bool known_allow_delete = false,
                                  uint64_t depth = 100) {
@@ -344,7 +335,6 @@
 };
 
 SnapshotFuzzEnv::SnapshotFuzzEnv() {
-    CheckUnsetGsidProps();
     CheckCleanupDeviceMapperDevices();
     CheckDetachLoopDevices();
     CheckUmountAll();
@@ -368,7 +358,6 @@
 }
 
 SnapshotFuzzEnv::~SnapshotFuzzEnv() {
-    CheckUnsetGsidProps();
     CheckCleanupDeviceMapperDevices();
     mounted_data_ = nullptr;
     auto_delete_data_mount_point_ = nullptr;
@@ -396,7 +385,7 @@
         const std::string& metadata_dir, const std::string& data_dir) {
     PCHECK(Mkdir(metadata_dir));
     PCHECK(Mkdir(data_dir));
-    return ImageManager::Open(metadata_dir, data_dir);
+    return SnapshotFuzzImageManager::Open(metadata_dir, data_dir);
 }
 
 // Helper to create a loop device for a file.
@@ -507,4 +496,21 @@
     return std::make_unique<AutoUnmount>(mount_point);
 }
 
+SnapshotFuzzImageManager::~SnapshotFuzzImageManager() {
+    // Remove relevant gsid.mapped_images.* props.
+    for (const auto& name : mapped_) {
+        CHECK(UnmapImageIfExists(name)) << "Cannot unmap " << name;
+    }
+}
+
+bool SnapshotFuzzImageManager::MapImageDevice(const std::string& name,
+                                              const std::chrono::milliseconds& timeout_ms,
+                                              std::string* path) {
+    if (impl_->MapImageDevice(name, timeout_ms, path)) {
+        mapped_.insert(name);
+        return true;
+    }
+    return false;
+}
+
 }  // namespace android::snapshot
diff --git a/fs_mgr/libsnapshot/snapshot_fuzz_utils.h b/fs_mgr/libsnapshot/snapshot_fuzz_utils.h
index 2405088..fa327b8 100644
--- a/fs_mgr/libsnapshot/snapshot_fuzz_utils.h
+++ b/fs_mgr/libsnapshot/snapshot_fuzz_utils.h
@@ -12,6 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include <memory>
+#include <set>
 #include <string>
 
 #include <android-base/file.h>
@@ -134,4 +136,68 @@
     bool CurrentSlotIsA() const { return data_->slot_suffix_is_a() != switched_slot_; }
 };
 
+// A spy class on ImageManager implementation. Upon destruction, unmaps all images
+// map through this object.
+class SnapshotFuzzImageManager : public android::fiemap::IImageManager {
+  public:
+    static std::unique_ptr<SnapshotFuzzImageManager> Open(const std::string& metadata_dir,
+                                                          const std::string& data_dir) {
+        auto impl = android::fiemap::ImageManager::Open(metadata_dir, data_dir);
+        if (impl == nullptr) return nullptr;
+        return std::unique_ptr<SnapshotFuzzImageManager>(
+                new SnapshotFuzzImageManager(std::move(impl)));
+    }
+
+    ~SnapshotFuzzImageManager();
+
+    // Spied APIs.
+    bool MapImageDevice(const std::string& name, const std::chrono::milliseconds& timeout_ms,
+                        std::string* path) override;
+
+    // Other functions call through.
+    android::fiemap::FiemapStatus CreateBackingImage(
+            const std::string& name, uint64_t size, int flags,
+            std::function<bool(uint64_t, uint64_t)>&& on_progress) override {
+        return impl_->CreateBackingImage(name, size, flags, std::move(on_progress));
+    }
+    bool DeleteBackingImage(const std::string& name) override {
+        return impl_->DeleteBackingImage(name);
+    }
+    bool UnmapImageDevice(const std::string& name) override {
+        return impl_->UnmapImageDevice(name);
+    }
+    bool BackingImageExists(const std::string& name) override {
+        return impl_->BackingImageExists(name);
+    }
+    bool IsImageMapped(const std::string& name) override { return impl_->IsImageMapped(name); }
+    bool MapImageWithDeviceMapper(const IPartitionOpener& opener, const std::string& name,
+                                  std::string* dev) override {
+        return impl_->MapImageWithDeviceMapper(opener, name, dev);
+    }
+    bool GetMappedImageDevice(const std::string& name, std::string* device) override {
+        return impl_->GetMappedImageDevice(name, device);
+    }
+    bool MapAllImages(const std::function<bool(std::set<std::string>)>& init) override {
+        return impl_->MapAllImages(init);
+    }
+    bool DisableImage(const std::string& name) override { return impl_->DisableImage(name); }
+    bool RemoveDisabledImages() override { return impl_->RemoveDisabledImages(); }
+    std::vector<std::string> GetAllBackingImages() override { return impl_->GetAllBackingImages(); }
+    android::fiemap::FiemapStatus ZeroFillNewImage(const std::string& name,
+                                                   uint64_t bytes) override {
+        return impl_->ZeroFillNewImage(name, bytes);
+    }
+    bool RemoveAllImages() override { return impl_->RemoveAllImages(); }
+    bool UnmapImageIfExists(const std::string& name) override {
+        return impl_->UnmapImageIfExists(name);
+    }
+
+  private:
+    std::unique_ptr<android::fiemap::IImageManager> impl_;
+    std::set<std::string> mapped_;
+
+    SnapshotFuzzImageManager(std::unique_ptr<android::fiemap::IImageManager>&& impl)
+        : impl_(std::move(impl)) {}
+};
+
 }  // namespace android::snapshot