From f3483ec6a0950b32c29b2ec30f3e256aaee0c279 Mon Sep 17 00:00:00 2001 From: Will McVicker Date: Wed, 29 Apr 2020 10:11:16 -0700 Subject: [PATCH] first_stage_init: add support to skip module load failures Extend androidboot.first_stage_console cmdline property to enable skipping module load failures without stopping at a serial console. This is useful for GKI development. Set androidboot.first_stage_console=2 for this behavior. Bug: 155296582 Test: verify behavior for values 0, 1, and 2 Merged-In: I068c631a22c848e45a421b297b1acae1b3deb3c1 Change-Id: I068c631a22c848e45a421b297b1acae1b3deb3c1 (cherry picked from commit 6c5f82642ba7cd770fde859273b01a8268d75dfc) --- init/first_stage_console.cpp | 15 +++++++++++++-- init/first_stage_console.h | 9 ++++++++- init/first_stage_init.cpp | 6 +++--- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/init/first_stage_console.cpp b/init/first_stage_console.cpp index cae53f440..cfa0d99ee 100644 --- a/init/first_stage_console.cpp +++ b/init/first_stage_console.cpp @@ -16,6 +16,7 @@ #include "first_stage_console.h" +#include #include #include #include @@ -87,8 +88,18 @@ void StartConsole() { _exit(127); } -bool FirstStageConsole(const std::string& cmdline) { - return cmdline.find("androidboot.first_stage_console=1") != std::string::npos; +int FirstStageConsole(const std::string& cmdline) { + auto pos = cmdline.find("androidboot.first_stage_console="); + if (pos != std::string::npos) { + int val = 0; + if (sscanf(cmdline.c_str() + pos, "androidboot.first_stage_console=%d", &val) != 1) { + return FirstStageConsoleParam::DISABLED; + } + if (val <= FirstStageConsoleParam::MAX_PARAM_VALUE && val >= 0) { + return val; + } + } + return FirstStageConsoleParam::DISABLED; } } // namespace init diff --git a/init/first_stage_console.h b/init/first_stage_console.h index 74853399b..8f36a7cbb 100644 --- a/init/first_stage_console.h +++ b/init/first_stage_console.h @@ -21,8 +21,15 @@ namespace android { namespace init { +enum FirstStageConsoleParam { + DISABLED = 0, + CONSOLE_ON_FAILURE = 1, + IGNORE_FAILURE = 2, + MAX_PARAM_VALUE = IGNORE_FAILURE, +}; + void StartConsole(); -bool FirstStageConsole(const std::string& cmdline); +int FirstStageConsole(const std::string& cmdline); } // namespace init } // namespace android diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp index 5eca64457..1a608f65b 100644 --- a/init/first_stage_init.cpp +++ b/init/first_stage_init.cpp @@ -200,16 +200,16 @@ int FirstStageMain(int argc, char** argv) { } Modprobe m({"/lib/modules"}, module_load_file); - auto want_console = ALLOW_FIRST_STAGE_CONSOLE && FirstStageConsole(cmdline); + auto want_console = ALLOW_FIRST_STAGE_CONSOLE ? FirstStageConsole(cmdline) : 0; if (!m.LoadListedModules(!want_console)) { - if (want_console) { + if (want_console != FirstStageConsoleParam::DISABLED) { LOG(ERROR) << "Failed to load kernel modules, starting console"; } else { LOG(FATAL) << "Failed to load kernel modules"; } } - if (want_console) { + if (want_console == FirstStageConsoleParam::CONSOLE_ON_FAILURE) { StartConsole(); }