From a619f22e376f397845cc91f47c1584be2050dc89 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Mon, 25 Jan 2021 09:53:35 -0800 Subject: [PATCH 1/2] first_stage_mount: Move CreateLogicalPartitions to DoFirstStageMount In preparation for later commit: first_stage_mount: Create snapshot devices before launching first_stage_console Bug: 173732805 Bug: 174685384 Change-Id: I6b77690c7cf68f6235c99bf4ff897b0ee41c4d0e Signed-off-by: Elliot Berman --- init/first_stage_mount.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp index 7c462814b..73072378f 100644 --- a/init/first_stage_mount.cpp +++ b/init/first_stage_mount.cpp @@ -253,6 +253,22 @@ bool FirstStageMount::DoFirstStageMount() { if (!InitDevices()) return false; + // Mount /metadata before creating logical partitions, since we need to + // know whether a snapshot merge is in progress. + auto metadata_partition = std::find_if(fstab_.begin(), fstab_.end(), [](const auto& entry) { + return entry.mount_point == "/metadata"; + }); + if (metadata_partition != fstab_.end()) { + if (MountPartition(metadata_partition, true /* erase_same_mounts */)) { + // Copies DSU AVB keys from the ramdisk to /metadata. + // Must be done before the following TrySwitchSystemAsRoot(). + // Otherwise, ramdisk will be inaccessible after switching root. + CopyDsuAvbKeys(); + } + } + + if (!CreateLogicalPartitions()) return false; + if (!MountPartitions()) return false; return true; @@ -505,22 +521,6 @@ bool FirstStageMount::TrySwitchSystemAsRoot() { } bool FirstStageMount::MountPartitions() { - // Mount /metadata before creating logical partitions, since we need to - // know whether a snapshot merge is in progress. - auto metadata_partition = std::find_if(fstab_.begin(), fstab_.end(), [](const auto& entry) { - return entry.mount_point == "/metadata"; - }); - if (metadata_partition != fstab_.end()) { - if (MountPartition(metadata_partition, true /* erase_same_mounts */)) { - // Copies DSU AVB keys from the ramdisk to /metadata. - // Must be done before the following TrySwitchSystemAsRoot(). - // Otherwise, ramdisk will be inaccessible after switching root. - CopyDsuAvbKeys(); - } - } - - if (!CreateLogicalPartitions()) return false; - if (!TrySwitchSystemAsRoot()) return false; if (!SkipMountingPartitions(&fstab_)) return false; From 9583e92257ab85075231b014f0999d5a5dab9910 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Mon, 25 Jan 2021 09:53:36 -0800 Subject: [PATCH 2/2] 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 --- init/first_stage_init.cpp | 6 +++++- init/first_stage_mount.cpp | 36 ++++++++++++++++++++++++++++-------- init/first_stage_mount.h | 3 ++- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp index 6954c03fb..f01a6c0ef 100644 --- a/init/first_stage_init.cpp +++ b/init/first_stage_init.cpp @@ -286,7 +286,11 @@ int FirstStageMain(int argc, char** argv) { } } + if (want_console == FirstStageConsoleParam::CONSOLE_ON_FAILURE) { + if (!DoCreateDevices()) { + LOG(ERROR) << "Failed to create device nodes early"; + } StartConsole(cmdline); } @@ -327,7 +331,7 @@ int FirstStageMain(int argc, char** argv) { } } - 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 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