sideload: mount snapshot partitions before merging

Before CleanupPreviousUpdateAction starts merging, in recovery,
create snapshot devices first.

Test: sideload, adb reboot sideload, then sideload again
Test: sideload, adb reboot sideload, rollback, then sideload again
Test: sideload, adb reboot (and wait until state merging),
      adb sideload, then sideload again.

Bug: 151983957
Change-Id: I2dc96faceb451dd956198e918ae530590eaee1e3
diff --git a/cleanup_previous_update_action.cc b/cleanup_previous_update_action.cc
index 91373d4..ee68947 100644
--- a/cleanup_previous_update_action.cc
+++ b/cleanup_previous_update_action.cc
@@ -18,6 +18,7 @@
 #include <chrono>  // NOLINT(build/c++11) -- for merge times
 #include <functional>
 #include <string>
+#include <type_traits>
 
 #include <android-base/properties.h>
 #include <base/bind.h>
@@ -163,6 +164,36 @@
     return;
   }
 
+  if (kIsRecovery) {
+    auto snapshots_created =
+        snapshot_->RecoveryCreateSnapshotDevices(metadata_device_);
+    switch (snapshots_created) {
+      case android::snapshot::CreateResult::CREATED: {
+        // If previous update has not finished merging, snapshots exists and are
+        // created here so that ProcessUpdateState can proceed.
+        LOG(INFO) << "Snapshot devices are created";
+        break;
+      }
+      case android::snapshot::CreateResult::NOT_CREATED: {
+        // If there is no previous update, no snapshot devices are created and
+        // ProcessUpdateState will return immediately. Hence, NOT_CREATED is not
+        // considered an error.
+        LOG(INFO) << "Snapshot devices are not created";
+        break;
+      }
+      case android::snapshot::CreateResult::ERROR:
+      default: {
+        LOG(ERROR)
+            << "Failed to create snapshot devices (CreateResult = "
+            << static_cast<
+                   std::underlying_type_t<android::snapshot::CreateResult>>(
+                   snapshots_created);
+        processor_->ActionComplete(this, ErrorCode::kError);
+        return;
+      }
+    }
+  }
+
   if (!merge_stats_->Start()) {
     // Not an error because CleanupPreviousUpdateAction may be paused and
     // resumed while kernel continues merging snapshots in the background.