Merge "first_stage_mount: Create snapshot devices before launching first_stage_console"
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index 551cf19..ff75aa3 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -298,7 +298,15 @@
                   << module_elapse_time.count() << " ms";
     }
 
+
+    bool created_devices = false;
     if (want_console == FirstStageConsoleParam::CONSOLE_ON_FAILURE) {
+        if (!IsRecoveryMode()) {
+            created_devices = DoCreateDevices();
+            if (!created_devices){
+                LOG(ERROR) << "Failed to create device nodes early";
+            }
+        }
         StartConsole(cmdline);
     }
 
@@ -339,7 +347,7 @@
         }
     }
 
-    if (!DoFirstStageMount()) {
+    if (!DoFirstStageMount(!created_devices)) {
         LOG(FATAL) << "Failed to mount required partitions early ...";
     }
 
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 7307237..de72f23 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -82,6 +82,7 @@
     // The factory method to create either FirstStageMountVBootV1 or FirstStageMountVBootV2
     // based on device tree configurations.
     static std::unique_ptr<FirstStageMount> Create();
+    bool DoCreateDevices();    // Creates devices and logical partitions from storage devices
     bool DoFirstStageMount();  // Mounts fstab entries read from device tree.
     bool InitDevices();
 
@@ -244,13 +245,7 @@
     }
 }
 
-bool FirstStageMount::DoFirstStageMount() {
-    if (!IsDmLinearEnabled() && fstab_.empty()) {
-        // Nothing to mount.
-        LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)";
-        return true;
-    }
-
+bool FirstStageMount::DoCreateDevices() {
     if (!InitDevices()) return false;
 
     // Mount /metadata before creating logical partitions, since we need to
@@ -269,6 +264,16 @@
 
     if (!CreateLogicalPartitions()) return false;
 
+    return true;
+}
+
+bool FirstStageMount::DoFirstStageMount() {
+    if (!IsDmLinearEnabled() && fstab_.empty()) {
+        // Nothing to mount.
+        LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)";
+        return true;
+    }
+
     if (!MountPartitions()) return false;
 
     return true;
@@ -829,8 +834,18 @@
 
 // Public functions
 // ----------------
+// Creates devices and logical partitions from storage devices
+bool DoCreateDevices() {
+    std::unique_ptr<FirstStageMount> handle = FirstStageMount::Create();
+    if (!handle) {
+        LOG(ERROR) << "Failed to create FirstStageMount";
+        return false;
+    }
+    return handle->DoCreateDevices();
+}
+
 // Mounts partitions specified by fstab in device tree.
-bool DoFirstStageMount() {
+bool DoFirstStageMount(bool create_devices) {
     // Skips first stage mount if we're in recovery mode.
     if (IsRecoveryMode()) {
         LOG(INFO) << "First stage mount skipped (recovery mode)";
@@ -842,6 +857,11 @@
         LOG(ERROR) << "Failed to create FirstStageMount";
         return false;
     }
+
+    if (create_devices) {
+        if (!handle->DoCreateDevices()) return false;
+    }
+
     return handle->DoFirstStageMount();
 }
 
diff --git a/init/first_stage_mount.h b/init/first_stage_mount.h
index 21d87fd..2f4e663 100644
--- a/init/first_stage_mount.h
+++ b/init/first_stage_mount.h
@@ -19,7 +19,8 @@
 namespace android {
 namespace init {
 
-bool DoFirstStageMount();
+bool DoCreateDevices();
+bool DoFirstStageMount(bool create_devices);
 void SetInitAvbVersionInRecovery();
 
 }  // namespace init