Merge "init: fix signal handling and LOG(FATAL) in child processes"
This commit is contained in:
commit
30bf4b7500
2 changed files with 20 additions and 6 deletions
|
|
@ -358,7 +358,7 @@ static void set_usb_controller() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void install_reboot_signal_handlers() {
|
static void InstallRebootSignalHandlers() {
|
||||||
// Instead of panic'ing the kernel as is the default behavior when init crashes,
|
// Instead of panic'ing the kernel as is the default behavior when init crashes,
|
||||||
// we prefer to reboot to bootloader on development builds, as this will prevent
|
// we prefer to reboot to bootloader on development builds, as this will prevent
|
||||||
// boot looping bad configurations and allow both developers and test farms to easily
|
// boot looping bad configurations and allow both developers and test farms to easily
|
||||||
|
|
@ -366,7 +366,13 @@ static void install_reboot_signal_handlers() {
|
||||||
struct sigaction action;
|
struct sigaction action;
|
||||||
memset(&action, 0, sizeof(action));
|
memset(&action, 0, sizeof(action));
|
||||||
sigfillset(&action.sa_mask);
|
sigfillset(&action.sa_mask);
|
||||||
action.sa_handler = [](int) {
|
action.sa_handler = [](int signal) {
|
||||||
|
// These signal handlers are also caught for processes forked from init, however we do not
|
||||||
|
// want them to trigger reboot, so we directly call _exit() for children processes here.
|
||||||
|
if (getpid() != 1) {
|
||||||
|
_exit(signal);
|
||||||
|
}
|
||||||
|
|
||||||
// Calling DoReboot() or LOG(FATAL) is not a good option as this is a signal handler.
|
// 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
|
// 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
|
// and probably good enough given this is already an error case and only enabled for
|
||||||
|
|
@ -396,7 +402,7 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (REBOOT_BOOTLOADER_ON_PANIC) {
|
if (REBOOT_BOOTLOADER_ON_PANIC) {
|
||||||
install_reboot_signal_handlers();
|
InstallRebootSignalHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);
|
bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);
|
||||||
|
|
|
||||||
14
init/log.cpp
14
init/log.cpp
|
|
@ -19,6 +19,7 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <linux/audit.h>
|
#include <linux/audit.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
#include <cutils/android_reboot.h>
|
#include <cutils/android_reboot.h>
|
||||||
|
|
@ -29,7 +30,14 @@
|
||||||
namespace android {
|
namespace android {
|
||||||
namespace init {
|
namespace init {
|
||||||
|
|
||||||
static void RebootAborter(const char* abort_message) {
|
static void InitAborter(const char* abort_message) {
|
||||||
|
// When init forks, it continues to use this aborter for LOG(FATAL), but we want children to
|
||||||
|
// simply abort instead of trying to reboot the system.
|
||||||
|
if (getpid() != 1) {
|
||||||
|
android::base::DefaultAborter(abort_message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// DoReboot() does a lot to try to shutdown the system cleanly. If something happens to call
|
// 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
|
// LOG(FATAL) in the shutdown path, we want to catch this and immediately use the syscall to
|
||||||
// reboot instead of recursing here.
|
// reboot instead of recursing here.
|
||||||
|
|
@ -49,7 +57,7 @@ void InitKernelLogging(char* argv[]) {
|
||||||
int fd = open("/sys/fs/selinux/null", O_RDWR);
|
int fd = open("/sys/fs/selinux/null", O_RDWR);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
int saved_errno = errno;
|
int saved_errno = errno;
|
||||||
android::base::InitLogging(argv, &android::base::KernelLogger, RebootAborter);
|
android::base::InitLogging(argv, &android::base::KernelLogger, InitAborter);
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
PLOG(FATAL) << "Couldn't open /sys/fs/selinux/null";
|
PLOG(FATAL) << "Couldn't open /sys/fs/selinux/null";
|
||||||
}
|
}
|
||||||
|
|
@ -58,7 +66,7 @@ void InitKernelLogging(char* argv[]) {
|
||||||
dup2(fd, 2);
|
dup2(fd, 2);
|
||||||
if (fd > 2) close(fd);
|
if (fd > 2) close(fd);
|
||||||
|
|
||||||
android::base::InitLogging(argv, &android::base::KernelLogger, RebootAborter);
|
android::base::InitLogging(argv, &android::base::KernelLogger, InitAborter);
|
||||||
}
|
}
|
||||||
|
|
||||||
int selinux_klog_callback(int type, const char *fmt, ...) {
|
int selinux_klog_callback(int type, const char *fmt, ...) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue