diff options
author | Tom Cherry <tomcherry@google.com> | 2018-09-27 16:10:46 -0700 |
---|---|---|
committer | Tom Cherry <tomcherry@google.com> | 2018-10-04 19:52:37 -0700 |
commit | 73f535e33b1fcb8088bc12c0431647286ef8ea44 (patch) | |
tree | 0f5bc65f909d3f89f56b720c09eef0fac0507211 /init/service.cpp | |
parent | 3da42a6c05311653ff5d12b5057d5f3c40ac0c1a (diff) | |
download | system_core-73f535e33b1fcb8088bc12c0431647286ef8ea44.tar.gz system_core-73f535e33b1fcb8088bc12c0431647286ef8ea44.tar.bz2 system_core-73f535e33b1fcb8088bc12c0431647286ef8ea44.zip |
init: allow customizable restart and timeout periods for services
Allow services to specify a custom restart period via the
restart_period service option. This will allow services to be run
periodically, such as a service that needs to run every hour.
Allow services to specify a timeout period via the timeout_period
service option. This will allow services to be killed after the
timeout expires if they are still running. This can be combined with
restart_period for creating period services.
Test: test app restarts every minute
Change-Id: Iad017820f9a602f9826104fb8cafc91bfb4b28d6
Diffstat (limited to 'init/service.cpp')
-rw-r--r-- | init/service.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/init/service.cpp b/init/service.cpp index d20e90a70..a3e59534e 100644 --- a/init/service.cpp +++ b/init/service.cpp @@ -627,6 +627,15 @@ Result<Success> Service::ParseProcessRlimit(const std::vector<std::string>& args return Success(); } +Result<Success> Service::ParseRestartPeriod(const std::vector<std::string>& args) { + int period; + if (!ParseInt(args[1], &period, 5)) { + return Error() << "restart_period value must be an integer >= 5"; + } + restart_period_ = std::chrono::seconds(period); + return Success(); +} + Result<Success> Service::ParseSeclabel(const std::vector<std::string>& args) { seclabel_ = args[1]; return Success(); @@ -650,6 +659,15 @@ Result<Success> Service::ParseShutdown(const std::vector<std::string>& args) { return Error() << "Invalid shutdown option"; } +Result<Success> Service::ParseTimeoutPeriod(const std::vector<std::string>& args) { + int period; + if (!ParseInt(args[1], &period, 1)) { + return Error() << "timeout_period value must be an integer >= 1"; + } + timeout_period_ = std::chrono::seconds(period); + return Success(); +} + template <typename T> Result<Success> Service::AddDescriptor(const std::vector<std::string>& args) { int perm = args.size() > 3 ? std::strtoul(args[3].c_str(), 0, 8) : -1; @@ -757,12 +775,16 @@ const Service::OptionParserMap::Map& Service::OptionParserMap::map() const { {1, 1, &Service::ParseOomScoreAdjust}}, {"override", {0, 0, &Service::ParseOverride}}, {"priority", {1, 1, &Service::ParsePriority}}, + {"restart_period", + {1, 1, &Service::ParseRestartPeriod}}, {"rlimit", {3, 3, &Service::ParseProcessRlimit}}, {"seclabel", {1, 1, &Service::ParseSeclabel}}, {"setenv", {2, 2, &Service::ParseSetenv}}, {"shutdown", {1, 1, &Service::ParseShutdown}}, {"sigstop", {0, 0, &Service::ParseSigstop}}, {"socket", {3, 6, &Service::ParseSocket}}, + {"timeout_period", + {1, 1, &Service::ParseTimeoutPeriod}}, {"user", {1, 1, &Service::ParseUser}}, {"writepid", {1, kMax, &Service::ParseWritepid}}, }; @@ -1022,6 +1044,18 @@ void Service::Terminate() { } } +void Service::Timeout() { + // All process state flags will be taken care of in Reap(), we really just want to kill the + // process here when it times out. Oneshot processes will transition to be disabled, and + // all other processes will transition to be restarting. + LOG(INFO) << "Service '" << name_ << "' expired its timeout of " << timeout_period_->count() + << " seconds and will now be killed"; + if (pid_) { + KillProcessGroup(SIGKILL); + NotifyStateChange("stopping"); + } +} + void Service::Restart() { if (flags_ & SVC_RUNNING) { /* Stop, wait, then start the service. */ |