Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 663fdfc1 authored by Tom Cherry's avatar Tom Cherry
Browse files

init: reboot to bootloader on crash for development builds

Currently, if init crashes, the kernel panics.  During development, we
would like to catch this crash before the kernel panics and reboot
into bootloader. This will prevent boot looping bad configurations,
particularly desired in test labs where manual intervention would
otherwise be required to reset the devices.

Keep the existing behavior for user builds, as init crashes should be
rare for production builds and rebooting the device is the correct
behavior for end users.

Bug: 34147472
Test: Boot bullhead userdebug, force init to crash, check that the
      device is in bootloader
Test: Boot bullhead user, force init to crash, check that the kernel
      panics and the device reboots as it did previously
Change-Id: Iab3d45ed0d1f82ffaad2a0835d9ca537c0516421
parent 5a258e72
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -5,9 +5,15 @@ LOCAL_PATH:= $(call my-dir)
# --

ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
init_options += -DALLOW_LOCAL_PROP_OVERRIDE=1 -DALLOW_PERMISSIVE_SELINUX=1
init_options += \
    -DALLOW_LOCAL_PROP_OVERRIDE=1 \
    -DALLOW_PERMISSIVE_SELINUX=1 \
    -DREBOOT_BOOTLOADER_ON_PANIC=1
else
init_options += -DALLOW_LOCAL_PROP_OVERRIDE=0 -DALLOW_PERMISSIVE_SELINUX=0
init_options += \
    -DALLOW_LOCAL_PROP_OVERRIDE=0 \
    -DALLOW_PERMISSIVE_SELINUX=0 \
    -DREBOOT_BOOTLOADER_ON_PANIC=0
endif

init_options += -DLOG_UEVENTS=0
+29 −0
Original line number Diff line number Diff line
@@ -1099,6 +1099,31 @@ done:
    return success;
}

static void install_reboot_signal_handlers() {
    // 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
    // boot looping bad configurations and allow both developers and test farms to easily
    // recover.
    struct sigaction action;
    memset(&action, 0, sizeof(action));
    sigfillset(&action.sa_mask);
    action.sa_handler = [](int) {
        // panic() reboots to bootloader
        panic();
    };
    action.sa_flags = SA_RESTART;
    sigaction(SIGABRT, &action, nullptr);
    sigaction(SIGBUS, &action, nullptr);
    sigaction(SIGFPE, &action, nullptr);
    sigaction(SIGILL, &action, nullptr);
    sigaction(SIGSEGV, &action, nullptr);
#if defined(SIGSTKFLT)
    sigaction(SIGSTKFLT, &action, nullptr);
#endif
    sigaction(SIGSYS, &action, nullptr);
    sigaction(SIGTRAP, &action, nullptr);
}

int main(int argc, char** argv) {
    if (!strcmp(basename(argv[0]), "ueventd")) {
        return ueventd_main(argc, argv);
@@ -1108,6 +1133,10 @@ int main(int argc, char** argv) {
        return watchdogd_main(argc, argv);
    }

    if (REBOOT_BOOTLOADER_ON_PANIC) {
        install_reboot_signal_handlers();
    }

    add_environment("PATH", _PATH_DEFPATH);

    bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);