From d96d0f7d58b947ae7e65a565f6e0ab13f2edbf73 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Mon, 25 Jan 2021 09:53:36 -0800 Subject: [PATCH] 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: I828ce999be6d786bf46dd5655dfda81d046906ab Signed-off-by: Elliot Berman --- init/first_stage_init.cpp | 10 +++++++++- init/first_stage_mount.cpp | 36 ++++++++++++++++++++++++++++-------- init/first_stage_mount.h | 3 ++- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp index 6954c03fb..2dd5145e0 100644 --- a/init/first_stage_init.cpp +++ b/init/first_stage_init.cpp @@ -286,7 +286,15 @@ int FirstStageMain(int argc, char** argv) { } } + + 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); } @@ -327,7 +335,7 @@ int FirstStageMain(int argc, char** argv) { } } - 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 73072378f..de72f23c3 100644 --- a/init/first_stage_mount.cpp +++ b/init/first_stage_mount.cpp @@ -82,6 +82,7 @@ class FirstStageMount { // The factory method to create either FirstStageMountVBootV1 or FirstStageMountVBootV2 // based on device tree configurations. static std::unique_ptr 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 @@ std::unique_ptr FirstStageMount::Create() { } } -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 @@ bool FirstStageMount::DoFirstStageMount() { 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 @@ bool FirstStageMountVBootV2::InitAvbHandle() { // Public functions // ---------------- +// Creates devices and logical partitions from storage devices +bool DoCreateDevices() { + std::unique_ptr 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 @@ bool DoFirstStageMount() { 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 21d87fd48..2f4e66382 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