diff --git a/init/README.md b/init/README.md index 957eb9e4a..4a5d0ec35 100644 --- a/init/README.md +++ b/init/README.md @@ -244,6 +244,10 @@ runs the service. "r", "w" or "rw". For native executables see libcutils android\_get\_control\_file(). +`gentle_kill` +> This service will be sent SIGTERM instead of SIGKILL when stopped. After a 200 ms timeout, it will + be sent SIGKILL. + `group [ \* ]` > Change to 'groupname' before exec'ing this service. Additional groupnames beyond the (required) first one are used to set the diff --git a/init/service.cpp b/init/service.cpp index b9b33090e..87d9c3a6c 100644 --- a/init/service.cpp +++ b/init/service.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -887,6 +888,10 @@ void Service::StopOrReset(int how) { } if (pid_) { + if (flags_ & SVC_GENTLE_KILL) { + KillProcessGroup(SIGTERM); + if (!process_cgroup_empty()) std::this_thread::sleep_for(200ms); + } KillProcessGroup(SIGKILL); NotifyStateChange("stopping"); } else { diff --git a/init/service.h b/init/service.h index f9749d207..3ef890299 100644 --- a/init/service.h +++ b/init/service.h @@ -56,6 +56,8 @@ // should not be killed during shutdown #define SVC_TEMPORARY 0x1000 // This service was started by 'exec' and should be removed from the // service list once it is reaped. +#define SVC_GENTLE_KILL 0x2000 // This service should be stopped with SIGTERM instead of SIGKILL + // Will still be SIGKILLed after timeout period of 200 ms #define NR_SVC_SUPP_GIDS 12 // twelve supplementary groups diff --git a/init/service_parser.cpp b/init/service_parser.cpp index 24a202444..356308423 100644 --- a/init/service_parser.cpp +++ b/init/service_parser.cpp @@ -151,6 +151,11 @@ Result ServiceParser::ParseEnterNamespace(std::vector&& args) return {}; } +Result ServiceParser::ParseGentleKill(std::vector&& args) { + service_->flags_ |= SVC_GENTLE_KILL; + return {}; +} + Result ServiceParser::ParseGroup(std::vector&& args) { auto gid = DecodeUid(args[1]); if (!gid.ok()) { @@ -584,6 +589,7 @@ const KeywordMap& ServiceParser::GetParserMap() con {"disabled", {0, 0, &ServiceParser::ParseDisabled}}, {"enter_namespace", {2, 2, &ServiceParser::ParseEnterNamespace}}, {"file", {2, 2, &ServiceParser::ParseFile}}, + {"gentle_kill", {0, 0, &ServiceParser::ParseGentleKill}}, {"group", {1, NR_SVC_SUPP_GIDS + 1, &ServiceParser::ParseGroup}}, {"interface", {2, 2, &ServiceParser::ParseInterface}}, {"ioprio", {2, 2, &ServiceParser::ParseIoprio}}, diff --git a/init/service_parser.h b/init/service_parser.h index 54503dd1c..670a5c6cd 100644 --- a/init/service_parser.h +++ b/init/service_parser.h @@ -53,6 +53,7 @@ class ServiceParser : public SectionParser { Result ParseDisabled(std::vector&& args); Result ParseEnterNamespace(std::vector&& args); Result ParseGroup(std::vector&& args); + Result ParseGentleKill(std::vector&& args); Result ParsePriority(std::vector&& args); Result ParseInterface(std::vector&& args); Result ParseIoprio(std::vector&& args);