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