Merge "init: replace panic() with LOG(FATAL)"

am: 57a89f3ba0

Change-Id: Ib00187f9296ea8afd2bd323a87e290e7424a864e
This commit is contained in:
Tom Cherry 2017-08-18 15:58:26 +00:00 committed by android-build-merger
commit ce2325895f
9 changed files with 42 additions and 38 deletions

View File

@ -34,6 +34,7 @@
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <cutils/android_reboot.h>
#include <keyutils.h>
#include <libavb/libavb.h>
#include <private/android_filesystem_config.h>
@ -252,8 +253,7 @@ static Result<Success> wait_for_coldboot_done_action(const std::vector<std::stri
// because any build that slow isn't likely to boot at all, and we'd
// rather any test lab devices fail back to the bootloader.
if (wait_for_file(COLDBOOT_DONE, 60s) < 0) {
LOG(ERROR) << "Timed out waiting for " COLDBOOT_DONE;
panic();
LOG(FATAL) << "Timed out waiting for " COLDBOOT_DONE;
}
property_set("ro.boottime.init.cold_boot_wait", std::to_string(t.duration().count()));
@ -367,8 +367,7 @@ static Result<Success> queue_property_triggers_action(const std::vector<std::str
static void global_seccomp() {
import_kernel_cmdline(false, [](const std::string& key, const std::string& value, bool in_qemu) {
if (key == "androidboot.seccomp" && value == "global" && !set_global_seccomp_filter()) {
LOG(ERROR) << "Failed to globally enable seccomp!";
panic();
LOG(FATAL) << "Failed to globally enable seccomp!";
}
});
}
@ -398,8 +397,11 @@ static void install_reboot_signal_handlers() {
memset(&action, 0, sizeof(action));
sigfillset(&action.sa_mask);
action.sa_handler = [](int) {
// panic() reboots to bootloader
panic();
// Calling DoReboot() or LOG(FATAL) is not a good option as this is a signal handler.
// RebootSystem uses syscall() which isn't actually async-signal-safe, but our only option
// and probably good enough given this is already an error case and only enabled for
// development builds.
RebootSystem(ANDROID_RB_RESTART2, "bootloader");
};
action.sa_flags = SA_RESTART;
sigaction(SIGABRT, &action, nullptr);
@ -468,8 +470,7 @@ int main(int argc, char** argv) {
LOG(INFO) << "init first stage started!";
if (!DoFirstStageMount()) {
LOG(ERROR) << "Failed to mount required partitions early ...";
panic();
LOG(FATAL) << "Failed to mount required partitions early ...";
}
SetInitAvbVersionInRecovery();
@ -484,8 +485,7 @@ int main(int argc, char** argv) {
// We're in the kernel domain, so re-exec init to transition to the init domain now
// that the SELinux policy has been loaded.
if (selinux_android_restorecon("/init", 0) == -1) {
PLOG(ERROR) << "restorecon failed of /init failed";
panic();
PLOG(FATAL) << "restorecon failed of /init failed";
}
setenv("INIT_SECOND_STAGE", "true", 1);
@ -500,8 +500,7 @@ int main(int argc, char** argv) {
// execv() only returns if an error happened, in which case we
// panic and never fall through this conditional.
PLOG(ERROR) << "execv(\"" << path << "\") failed";
panic();
PLOG(FATAL) << "execv(\"" << path << "\") failed";
}
// At this point we're in the second stage of init.

View File

@ -21,17 +21,35 @@
#include <string.h>
#include <android-base/logging.h>
#include <cutils/android_reboot.h>
#include <selinux/selinux.h>
#include "reboot.h"
namespace android {
namespace init {
static void RebootAborter(const char* abort_message) {
// DoReboot() does a lot to try to shutdown the system cleanly. If something happens to call
// LOG(FATAL) in the shutdown path, we want to catch this and immediately use the syscall to
// reboot instead of recursing here.
static bool has_aborted = false;
if (!has_aborted) {
has_aborted = true;
// Do not queue "shutdown" trigger since we want to shutdown immediately and it's not likely
// that we can even run the ActionQueue at this point.
DoReboot(ANDROID_RB_RESTART2, "reboot", "bootloader", false);
} else {
RebootSystem(ANDROID_RB_RESTART2, "bootloader");
}
}
void InitKernelLogging(char* argv[]) {
// Make stdin/stdout/stderr all point to /dev/null.
int fd = open("/sys/fs/selinux/null", O_RDWR);
if (fd == -1) {
int saved_errno = errno;
android::base::InitLogging(argv, &android::base::KernelLogger);
android::base::InitLogging(argv, &android::base::KernelLogger, RebootAborter);
errno = saved_errno;
PLOG(FATAL) << "Couldn't open /sys/fs/selinux/null";
}
@ -40,7 +58,7 @@ void InitKernelLogging(char* argv[]) {
dup2(fd, 2);
if (fd > 2) close(fd);
android::base::InitLogging(argv, &android::base::KernelLogger);
android::base::InitLogging(argv, &android::base::KernelLogger, RebootAborter);
}
int selinux_klog_callback(int type, const char *fmt, ...) {

View File

@ -191,8 +191,7 @@ static bool IsRebootCapable() {
return value == CAP_SET;
}
static void __attribute__((noreturn))
RebootSystem(unsigned int cmd, const std::string& rebootTarget) {
void __attribute__((noreturn)) RebootSystem(unsigned int cmd, const std::string& rebootTarget) {
LOG(INFO) << "Reboot ending, jumping to kernel";
if (!IsRebootCapable()) {
@ -216,7 +215,7 @@ RebootSystem(unsigned int cmd, const std::string& rebootTarget) {
break;
}
// In normal case, reboot should not return.
PLOG(FATAL) << "reboot call returned";
PLOG(ERROR) << "reboot call returned";
abort();
}

View File

@ -22,6 +22,9 @@
namespace android {
namespace init {
// This is a wrapper around the actual reboot calls. DoReboot() should be preferred in most cases.
void __attribute__((noreturn)) RebootSystem(unsigned int cmd, const std::string& rebootTarget);
/* Reboot / shutdown the system.
* cmd ANDROID_RB_* as defined in android_reboot.h
* reason Reason string like "reboot", "userrequested"

View File

@ -25,8 +25,6 @@
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include "util.h"
using android::base::unique_fd;
namespace android {
@ -178,8 +176,7 @@ Result<Success> SetMmapRndBitsAction(const std::vector<std::string>& args) {
LOG(ERROR) << "Unknown architecture";
#endif
LOG(ERROR) << "Unable to set adequate mmap entropy value!";
panic();
LOG(FATAL) << "Unable to set adequate mmap entropy value!";
return Error();
}
@ -194,8 +191,7 @@ Result<Success> SetKptrRestrictAction(const std::vector<std::string>& args) {
std::string path = KPTR_RESTRICT_PATH;
if (!SetHighestAvailableOptionValue(path, KPTR_RESTRICT_MINVALUE, KPTR_RESTRICT_MAXVALUE)) {
LOG(ERROR) << "Unable to set adequate kptr_restrict value!";
panic();
LOG(FATAL) << "Unable to set adequate kptr_restrict value!";
return Error();
}
return Success();

View File

@ -345,21 +345,19 @@ void SelinuxInitialize() {
LOG(INFO) << "Loading SELinux policy";
if (!LoadPolicy()) {
panic();
LOG(FATAL) << "Unable to load SELinux policy";
}
bool kernel_enforcing = (security_getenforce() == 1);
bool is_enforcing = IsEnforcing();
if (kernel_enforcing != is_enforcing) {
if (security_setenforce(is_enforcing)) {
PLOG(ERROR) << "security_setenforce(%s) failed" << (is_enforcing ? "true" : "false");
panic();
PLOG(FATAL) << "security_setenforce(%s) failed" << (is_enforcing ? "true" : "false");
}
}
if (auto result = WriteFile("/sys/fs/selinux/checkreqprot", "0"); !result) {
LOG(ERROR) << "Unable to write to /sys/fs/selinux/checkreqprot: " << result.error();
panic();
LOG(FATAL) << "Unable to write to /sys/fs/selinux/checkreqprot: " << result.error();
}
// init's first stage can't set properties, so pass the time to the second stage.

View File

@ -306,8 +306,7 @@ void Service::Reap() {
if ((flags_ & SVC_CRITICAL) && !(flags_ & SVC_RESTART)) {
if (now < time_crashed_ + 4min) {
if (++crash_count_ > 4) {
LOG(ERROR) << "critical process '" << name_ << "' exited 4 times in 4 minutes";
panic();
LOG(FATAL) << "critical process '" << name_ << "' exited 4 times in 4 minutes";
}
} else {
time_crashed_ = now;

View File

@ -345,12 +345,6 @@ bool expand_props(const std::string& src, std::string* dst) {
return true;
}
void panic() {
LOG(ERROR) << "panic: rebooting to bootloader";
// Do not queue "shutdown" trigger since we want to shutdown immediately
DoReboot(ANDROID_RB_RESTART2, "reboot", "bootloader", false);
}
static std::string init_android_dt_dir() {
// Use the standard procfs-based path by default
std::string android_dt_dir = kDefaultAndroidDtDir;

View File

@ -55,8 +55,6 @@ std::string bytes_to_hex(const uint8_t *bytes, size_t bytes_len);
bool is_dir(const char* pathname);
bool expand_props(const std::string& src, std::string* dst);
void panic() __attribute__((__noreturn__));
// Returns the platform's Android DT directory as specified in the kernel cmdline.
// If the platform does not configure a custom DT path, returns the standard one (based in procfs).
const std::string& get_android_dt_dir();