first_stage_mount: Create snapshot devices before launching first_stage_console

During device bringup, dynamic partitions may not be properly
configured by some sort of build or load misconfiguration. Diagnosing
such issues can be difficult without being able to see which partitions
are available and what they contain.

Aditionally, making logical partitions available to first stage console
permits early mounting of vendor partition and allows primitive
validation of vendor scripts without requiring full Android
environment. For instance, vendor_dlkm partition and modules can be
probed needing to have a full Android bootup.

Creation of logical partitions is done only when first_stage_console is
requested in order to have minimal impact on normal boot. Thus, only a
small refactor is required to split CreateLogicalPartitions out of
MountPartitions.

Bug: 174685384
Bug: 173732805
Change-Id: I82b7d77b9dc75af59b5e18b574e3eb99c8aff9e2
Signed-off-by: Elliot Berman <eberman@quicinc.com>
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index 6954c03..f01a6c0 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -286,7 +286,11 @@
         }
     }
 
+
     if (want_console == FirstStageConsoleParam::CONSOLE_ON_FAILURE) {
+        if (!DoCreateDevices()) {
+            LOG(ERROR) << "Failed to create device nodes early";
+        }
         StartConsole(cmdline);
     }
 
@@ -327,7 +331,7 @@
         }
     }
 
-    if (!DoFirstStageMount()) {
+    if (!DoFirstStageMount(want_console != FirstStageConsoleParam::CONSOLE_ON_FAILURE)) {
         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