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
This commit is contained in:
parent
59656fb377
commit
75e13baf32
|
@ -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