summaryrefslogtreecommitdiff
path: root/init/service_parser.cpp
diff options
context:
space:
mode:
authorWoody Lin <woodylin@google.com>2019-12-26 22:22:28 +0800
committerWoody Lin <woodylin@google.com>2020-10-26 11:38:01 +0800
commit45215ae6e5742d9dff5468d744a02013e3efbef7 (patch)
treeea9154cc17b51d7695e2f5c6f86828ee0fe92beb /init/service_parser.cpp
parent45662c8941df873d4d6e50f189129d5bcbf365e9 (diff)
init/service_parser: Add arguments `window' and `target' for `critical'
The critical services can now using the interface `critical [window=<fatal crash window mins>] [target=<fatal reboot target>]` to setup the timing window that when there are more than 4 crashes in it, the init will regard it as a fatal system error and reboot the system. Config `window=${zygote.critical_window.minute:-off}' and `target=zygote-fatal' for all system-server services, so platform that configures ro.boot.zygote_critical_window can escape the system-server crash-loop via init fatal handler. Bug: 146818493 Change-Id: Ib2dc253616be6935ab9ab52184a1b6394665e813
Diffstat (limited to 'init/service_parser.cpp')
-rw-r--r--init/service_parser.cpp35
1 files changed, 34 insertions, 1 deletions
diff --git a/init/service_parser.cpp b/init/service_parser.cpp
index bdac0777b..97621dac6 100644
--- a/init/service_parser.cpp
+++ b/init/service_parser.cpp
@@ -93,6 +93,39 @@ Result<void> ServiceParser::ParseConsole(std::vector<std::string>&& args) {
}
Result<void> ServiceParser::ParseCritical(std::vector<std::string>&& args) {
+ std::optional<std::string> fatal_reboot_target;
+ std::optional<std::chrono::minutes> fatal_crash_window;
+
+ for (auto it = args.begin() + 1; it != args.end(); ++it) {
+ auto arg = android::base::Split(*it, "=");
+ if (arg.size() != 2) {
+ return Error() << "critical: Argument '" << *it << "' is not supported";
+ } else if (arg[0] == "target") {
+ fatal_reboot_target = arg[1];
+ } else if (arg[0] == "window") {
+ int minutes;
+ auto window = ExpandProps(arg[1]);
+ if (!window.ok()) {
+ return Error() << "critical: Could not expand argument ': " << arg[1];
+ }
+ if (*window == "off") {
+ return {};
+ }
+ if (!ParseInt(*window, &minutes, 0)) {
+ return Error() << "critical: 'fatal_crash_window' must be an integer > 0";
+ }
+ fatal_crash_window = std::chrono::minutes(minutes);
+ } else {
+ return Error() << "critical: Argument '" << *it << "' is not supported";
+ }
+ }
+
+ if (fatal_reboot_target) {
+ service_->fatal_reboot_target_ = *fatal_reboot_target;
+ }
+ if (fatal_crash_window) {
+ service_->fatal_crash_window_ = *fatal_crash_window;
+ }
service_->flags_ |= SVC_CRITICAL;
return {};
}
@@ -506,7 +539,7 @@ const KeywordMap<ServiceParser::OptionParser>& ServiceParser::GetParserMap() con
{"capabilities", {0, kMax, &ServiceParser::ParseCapabilities}},
{"class", {1, kMax, &ServiceParser::ParseClass}},
{"console", {0, 1, &ServiceParser::ParseConsole}},
- {"critical", {0, 0, &ServiceParser::ParseCritical}},
+ {"critical", {0, 2, &ServiceParser::ParseCritical}},
{"disabled", {0, 0, &ServiceParser::ParseDisabled}},
{"enter_namespace", {2, 2, &ServiceParser::ParseEnterNamespace}},
{"file", {2, 2, &ServiceParser::ParseFile}},