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

Commit 69596c2d authored by Luis Hector Chavez's avatar Luis Hector Chavez Committed by android-build-merger
Browse files

Merge "init: Allow clean system shutdown upon SIGTERM" am: 61cb88ad

am: 721b2d60

Change-Id: Id420e18f64e3abba6bd50a444ff4f9b05db3dc2d
parents 7de24983 721b2d60
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -119,7 +119,7 @@ cc_binary {
        "init_first_stage.cpp",
        "keychords.cpp",
        "reboot.cpp",
        "signal_handler.cpp",
        "sigchld_handler.cpp",
        "ueventd.cpp",
        "watchdogd.cpp",
    ],
+1 −1
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ LOCAL_SRC_FILES:= \
    init_first_stage.cpp \
    keychords.cpp \
    reboot.cpp \
    signal_handler.cpp \
    sigchld_handler.cpp \
    ueventd.cpp \
    watchdogd.cpp \

+0 −1
Original line number Diff line number Diff line
@@ -66,7 +66,6 @@
#include "reboot.h"
#include "rlimit_parser.h"
#include "service.h"
#include "signal_handler.h"
#include "util.h"

using namespace std::literals::string_literals;
+45 −2
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <string.h>
#include <sys/epoll.h>
#include <sys/mount.h>
#include <sys/signalfd.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <unistd.h>
@@ -51,7 +52,7 @@
#include "reboot.h"
#include "security.h"
#include "selinux.h"
#include "signal_handler.h"
#include "sigchld_handler.h"
#include "ueventd.h"
#include "util.h"
#include "watchdogd.h"
@@ -72,6 +73,7 @@ static char qemu[32];
std::string default_console = "/dev/console";

static int epoll_fd = -1;
static int sigterm_signal_fd = -1;

static std::unique_ptr<Timer> waiting_for_prop(nullptr);
static std::string wait_prop_name;
@@ -392,6 +394,41 @@ static void InstallRebootSignalHandlers() {
    sigaction(SIGTRAP, &action, nullptr);
}

static void HandleSigtermSignal() {
    signalfd_siginfo siginfo;
    ssize_t bytes_read = TEMP_FAILURE_RETRY(read(sigterm_signal_fd, &siginfo, sizeof(siginfo)));
    if (bytes_read != sizeof(siginfo)) {
        PLOG(ERROR) << "Failed to read siginfo from sigterm_signal_fd";
        return;
    }

    if (siginfo.ssi_pid != 0) {
        // Drop any userspace SIGTERM requests.
        LOG(DEBUG) << "Ignoring SIGTERM from pid " << siginfo.ssi_pid;
        return;
    }

    LOG(INFO) << "Handling SIGTERM, shutting system down";
    HandlePowerctlMessage("shutdown");
}

static void InstallSigtermHandler() {
    sigset_t mask;
    sigemptyset(&mask);
    sigaddset(&mask, SIGTERM);

    if (sigprocmask(SIG_BLOCK, &mask, nullptr) == -1) {
        PLOG(FATAL) << "failed to block SIGTERM";
    }

    sigterm_signal_fd = signalfd(-1, &mask, SFD_CLOEXEC);
    if (sigterm_signal_fd == -1) {
        PLOG(FATAL) << "failed to create signalfd for SIGTERM";
    }

    register_epoll_handler(sigterm_signal_fd, HandleSigtermSignal);
}

int main(int argc, char** argv) {
    if (!strcmp(basename(argv[0]), "ueventd")) {
        return ueventd_main(argc, argv);
@@ -527,7 +564,13 @@ int main(int argc, char** argv) {
        exit(1);
    }

    signal_handler_init();
    sigchld_handler_init();

    if (!IsRebootCapable()) {
        // If init does not have the CAP_SYS_BOOT capability, it is running in a container.
        // In that case, receiving SIGTERM will cause the system to shut down.
        InstallSigtermHandler();
    }

    property_load_boot_defaults();
    export_oem_lock_status();
+2 −4
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@
#include "init.h"
#include "property_service.h"
#include "service.h"
#include "signal_handler.h"
#include "sigchld_handler.h"

using android::base::StringPrintf;
using android::base::Timer;
@@ -169,9 +169,7 @@ static void LogShutdownTime(UmountStat stat, Timer* t) {
                 << stat;
}

// 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.
static bool IsRebootCapable() {
bool IsRebootCapable() {
    if (!CAP_IS_SUPPORTED(CAP_SYS_BOOT)) {
        PLOG(WARNING) << "CAP_SYS_BOOT is not supported";
        return true;
Loading