diff options
author | Bertrand SIMONNET <bsimonnet@google.com> | 2015-12-18 11:39:59 -0800 |
---|---|---|
committer | Bertrand SIMONNET <bsimonnet@google.com> | 2016-01-08 11:12:15 -0800 |
commit | b7e03e82b89a30b09fea88eaf2a5638df1017cf6 (patch) | |
tree | 4a82e891ea154a1ac42c736e120a1b8e985c5a06 /init/signal_handler.cpp | |
parent | a649a7df15617e1e54cc89c2f682a5e6472bf304 (diff) |
init: Allows shutting down cleanly.
When ro.build.shutdown_timeout is set, init will send a SIGTERM signal to
all services on reboot. The normal shutdown process will continue once
all services have exited or after the shutdown timeout
(ro.build.shutdown_timeout).
If ro.build.shutdown_timeout is not set, we assume a 0s timeout.
Bug: 26216447
Test: manual: Ask to reboot. All services exit cleanly.
Change-Id: If921f6e8d87211e500ac9fa86f3e1eabe02d18cf
Diffstat (limited to 'init/signal_handler.cpp')
-rw-r--r-- | init/signal_handler.cpp | 54 |
1 files changed, 2 insertions, 52 deletions
diff --git a/init/signal_handler.cpp b/init/signal_handler.cpp index e7d42cb9b..ea483d4e2 100644 --- a/init/signal_handler.cpp +++ b/init/signal_handler.cpp @@ -37,62 +37,12 @@ static int signal_write_fd = -1; static int signal_read_fd = -1; -static std::string DescribeStatus(int status) { - if (WIFEXITED(status)) { - return android::base::StringPrintf("exited with status %d", WEXITSTATUS(status)); - } else if (WIFSIGNALED(status)) { - return android::base::StringPrintf("killed by signal %d", WTERMSIG(status)); - } else if (WIFSTOPPED(status)) { - return android::base::StringPrintf("stopped by signal %d", WSTOPSIG(status)); - } else { - return "state changed"; - } -} - -static bool wait_for_one_process() { - int status; - pid_t pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG)); - if (pid == 0) { - return false; - } else if (pid == -1) { - ERROR("waitpid failed: %s\n", strerror(errno)); - return false; - } - - Service* svc = ServiceManager::GetInstance().FindServiceByPid(pid); - - std::string name; - if (svc) { - name = android::base::StringPrintf("Service '%s' (pid %d)", svc->name().c_str(), pid); - } else { - name = android::base::StringPrintf("Untracked pid %d", pid); - } - - NOTICE("%s %s\n", name.c_str(), DescribeStatus(status).c_str()); - - if (!svc) { - return true; - } - - if (svc->Reap()) { - waiting_for_exec = false; - ServiceManager::GetInstance().RemoveService(*svc); - } - - return true; -} - -static void reap_any_outstanding_children() { - while (wait_for_one_process()) { - } -} - static void handle_signal() { // Clear outstanding requests. char buf[32]; read(signal_read_fd, buf, sizeof(buf)); - reap_any_outstanding_children(); + ServiceManager::GetInstance().ReapAnyOutstandingChildren(); } static void SIGCHLD_handler(int) { @@ -119,7 +69,7 @@ void signal_handler_init() { act.sa_flags = SA_NOCLDSTOP; sigaction(SIGCHLD, &act, 0); - reap_any_outstanding_children(); + ServiceManager::GetInstance().ReapAnyOutstandingChildren(); register_epoll_handler(signal_read_fd, handle_signal); } |