diff options
author | Woody Lin <woodylin@google.com> | 2019-12-26 22:22:28 +0800 |
---|---|---|
committer | Woody Lin <woodylin@google.com> | 2020-10-26 11:38:01 +0800 |
commit | 45215ae6e5742d9dff5468d744a02013e3efbef7 (patch) | |
tree | ea9154cc17b51d7695e2f5c6f86828ee0fe92beb /init/service_parser.cpp | |
parent | 45662c8941df873d4d6e50f189129d5bcbf365e9 (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.cpp | 35 |
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}}, |