summaryrefslogtreecommitdiffstats
path: root/init/service.cpp
diff options
context:
space:
mode:
authorTom Cherry <tomcherry@google.com>2018-09-27 16:10:46 -0700
committerTom Cherry <tomcherry@google.com>2018-10-04 19:52:37 -0700
commit73f535e33b1fcb8088bc12c0431647286ef8ea44 (patch)
tree0f5bc65f909d3f89f56b720c09eef0fac0507211 /init/service.cpp
parent3da42a6c05311653ff5d12b5057d5f3c40ac0c1a (diff)
downloadsystem_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.cpp34
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. */