init: make fatal reboot target configurable
Currently, if init encounters a fatal issues it reboots to fastboot
but this may be not desirable in all cases, especially the case of
critical services crashing. Therefore this change adds the ability
for vendors to customize the reboot target via the
androidboot.init_fatal_reboot_target= kernel command line.
This applies to all LOG(FATAL) messages as well as fatal signals in
userdebug/eng builds, except for signals before logging is enabled in
first stage init.
Bug: 121006328
Test: device reboots to configurable target with LOG(FATAL)
Test: device reboots to configurable target after a segfault in the
various stages of init
Test: device reboots to fastboot without a configured target
Change-Id: I16ea9e32e2fee08dece3d33b697d7a08191d607b
Merged-In: I16ea9e32e2fee08dece3d33b697d7a08191d607b
(cherry picked from commit 75e13baf32
)
This commit is contained in:
parent
1fcd51255a
commit
b80149d8bc
|
@ -45,6 +45,7 @@ uint32_t HandlePropertySet(const std::string& name, const std::string& value,
|
|||
const std::string& source_context, const ucred& cr, std::string* error);
|
||||
|
||||
// reboot_utils.h
|
||||
inline void SetFatalRebootTarget() {}
|
||||
inline void __attribute__((noreturn)) InitFatalReboot() {
|
||||
abort();
|
||||
}
|
||||
|
|
|
@ -32,6 +32,27 @@
|
|||
namespace android {
|
||||
namespace init {
|
||||
|
||||
static std::string init_fatal_reboot_target = "bootloader";
|
||||
|
||||
void SetFatalRebootTarget() {
|
||||
std::string cmdline;
|
||||
android::base::ReadFileToString("/proc/cmdline", &cmdline);
|
||||
cmdline = android::base::Trim(cmdline);
|
||||
|
||||
const char kRebootTargetString[] = "androidboot.init_fatal_reboot_target=";
|
||||
auto start_pos = cmdline.find(kRebootTargetString);
|
||||
if (start_pos == std::string::npos) {
|
||||
return; // We already default to bootloader if no setting is provided.
|
||||
}
|
||||
start_pos += sizeof(kRebootTargetString) - 1;
|
||||
|
||||
auto end_pos = cmdline.find(' ', start_pos);
|
||||
// if end_pos isn't found, then we've run off the end, but this is okay as this is the last
|
||||
// entry, and -1 is a valid size for string::substr();
|
||||
auto size = end_pos == std::string::npos ? -1 : end_pos - start_pos;
|
||||
init_fatal_reboot_target = cmdline.substr(start_pos, size);
|
||||
}
|
||||
|
||||
bool IsRebootCapable() {
|
||||
if (!CAP_IS_SUPPORTED(CAP_SYS_BOOT)) {
|
||||
PLOG(WARNING) << "CAP_SYS_BOOT is not supported";
|
||||
|
@ -85,13 +106,13 @@ void __attribute__((noreturn)) InitFatalReboot() {
|
|||
|
||||
if (pid == -1) {
|
||||
// Couldn't fork, don't even try to backtrace, just reboot.
|
||||
RebootSystem(ANDROID_RB_RESTART2, "bootloader");
|
||||
RebootSystem(ANDROID_RB_RESTART2, init_fatal_reboot_target);
|
||||
} else if (pid == 0) {
|
||||
// Fork a child for safety, since we always want to shut down if something goes wrong, but
|
||||
// its worth trying to get the backtrace, even in the signal handler, since typically it
|
||||
// does work despite not being async-signal-safe.
|
||||
sleep(5);
|
||||
RebootSystem(ANDROID_RB_RESTART2, "bootloader");
|
||||
RebootSystem(ANDROID_RB_RESTART2, init_fatal_reboot_target);
|
||||
}
|
||||
|
||||
// In the parent, let's try to get a backtrace then shutdown.
|
||||
|
@ -103,7 +124,7 @@ void __attribute__((noreturn)) InitFatalReboot() {
|
|||
for (size_t i = 0; i < backtrace->NumFrames(); i++) {
|
||||
LOG(ERROR) << backtrace->FormatFrameData(i);
|
||||
}
|
||||
RebootSystem(ANDROID_RB_RESTART2, "bootloader");
|
||||
RebootSystem(ANDROID_RB_RESTART2, init_fatal_reboot_target);
|
||||
}
|
||||
|
||||
void InstallRebootSignalHandlers() {
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
namespace android {
|
||||
namespace init {
|
||||
|
||||
void SetFatalRebootTarget();
|
||||
// Determines whether the system is capable of rebooting. This is conservative,
|
||||
// so if any of the attempts to determine this fail, it will still return true.
|
||||
bool IsRebootCapable();
|
||||
|
|
|
@ -468,6 +468,7 @@ void SetStdioToDevNull(char** argv) {
|
|||
}
|
||||
|
||||
void InitKernelLogging(char** argv) {
|
||||
SetFatalRebootTarget();
|
||||
android::base::InitLogging(argv, &android::base::KernelLogger, InitAborter);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue