Merge "Mount snapshotted /system in Virtual A/B devices"
diff --git a/install/include/install/snapshot_utils.h b/install/include/install/snapshot_utils.h
index 00c3ef7..f4b978d 100644
--- a/install/include/install/snapshot_utils.h
+++ b/install/include/install/snapshot_utils.h
@@ -19,3 +19,12 @@
 #include "recovery_ui/device.h"
 
 bool FinishPendingSnapshotMerges(Device* device);
+
+/*
+ * This function tries to create the snapshotted devices in the case a Virtual
+ * A/B device is updating.
+ * The function returns false in case of critical failure that would prevent
+ * the further mountings of devices, or true in case of success, if either the
+ * devices were created or there was no need to.
+ */
+bool CreateSnapshotPartitions();
diff --git a/install/snapshot_utils.cpp b/install/snapshot_utils.cpp
index 69da5ee..7235e67 100644
--- a/install/snapshot_utils.cpp
+++ b/install/snapshot_utils.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#include <android-base/logging.h>
 #include <android-base/properties.h>
 #include <libsnapshot/snapshot.h>
 
@@ -22,6 +23,7 @@
 #include "recovery_ui/ui.h"
 #include "recovery_utils/roots.h"
 
+using android::snapshot::CreateResult;
 using android::snapshot::SnapshotManager;
 
 bool FinishPendingSnapshotMerges(Device* device) {
@@ -47,3 +49,26 @@
   }
   return true;
 }
+
+bool CreateSnapshotPartitions() {
+  if (!android::base::GetBoolProperty("ro.virtual_ab.enabled", false)) {
+    // If the device does not support Virtual A/B, there's no need to create
+    // snapshot devices.
+    return true;
+  }
+
+  auto sm = SnapshotManager::NewForFirstStageMount();
+  if (!sm) {
+    // SnapshotManager could not be created. The device is still in a
+    // consistent state and can continue with the mounting of the existing
+    // devices, but cannot initialize snapshot devices.
+    LOG(WARNING) << "Could not create SnapshotManager";
+    return true;
+  }
+
+  auto ret = sm->RecoveryCreateSnapshotDevices();
+  if (ret == CreateResult::ERROR) {
+    return false;
+  }
+  return true;
+}
diff --git a/recovery.cpp b/recovery.cpp
index f59a940..e4b8e45 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -50,6 +50,7 @@
 #include "install/fuse_install.h"
 #include "install/install.h"
 #include "install/package.h"
+#include "install/snapshot_utils.h"
 #include "install/wipe_data.h"
 #include "install/wipe_device.h"
 #include "otautil/boot_state.h"
@@ -437,7 +438,13 @@
         screen_ui->CheckBackgroundTextImages();
         break;
       }
+
       case Device::MOUNT_SYSTEM:
+        // For Virtual A/B, set up the snapshot devices (if exist).
+        if (!CreateSnapshotPartitions()) {
+          ui->Print("Virtual A/B: snapshot partitions creation failed.\n");
+          break;
+        }
         if (ensure_path_mounted_at(android::fs_mgr::GetSystemRoot(), "/mnt/system") != -1) {
           ui->Print("Mounted /system.\n");
         }