init: Add task_profiles init command
Introduce new command to allow setting task profiles from inside .rc
script. This is to replace usage of writepid when a service is trying
to join a cgroup. Usage example from a .rc file:
service surfaceflinger /system/bin/surfaceflinger
task_profiles HighPerformance
Bug: 155419956
Test: change .rc file and confirm task profile is applied
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Change-Id: I0add9c3b363a7cb1ea89778780896cae1c8a303c
diff --git a/init/README.md b/init/README.md
index 13f1bac..726c0cc 100644
--- a/init/README.md
+++ b/init/README.md
@@ -322,6 +322,10 @@
This is mutually exclusive with the console option, which additionally connects stdin to the
given console.
+`task_profiles <profile> [ <profile>\* ]`
+> Set task profiles for the process when it forks. This is designed to replace the use of
+ writepid option for moving a process into a cgroup.
+
`timeout_period <seconds>`
> Provide a timeout after which point the service will be killed. The oneshot keyword is respected
here, so oneshot services do not automatically restart, however all other services will.
@@ -356,6 +360,8 @@
cgroup/cpuset usage. If no files under /dev/cpuset/ are specified, but the
system property 'ro.cpuset.default' is set to a non-empty cpuset name (e.g.
'/foreground'), then the pid is written to file /dev/cpuset/_cpuset\_name_/tasks.
+ The use of this option for moving a process into a cgroup is obsolete. Please
+ use task_profiles option instead.
Triggers
diff --git a/init/service.cpp b/init/service.cpp
index 20400a0..165b848 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -513,6 +513,10 @@
LOG(ERROR) << "failed to write pid to files: " << result.error();
}
+ if (task_profiles_.size() > 0 && !SetTaskProfiles(getpid(), task_profiles_)) {
+ LOG(ERROR) << "failed to set task profiles";
+ }
+
// As requested, set our gid, supplemental gids, uid, context, and
// priority. Aborts on failure.
SetProcessAttributesAndCaps();
diff --git a/init/service.h b/init/service.h
index 9f1d697..34ed5ef 100644
--- a/init/service.h
+++ b/init/service.h
@@ -170,6 +170,8 @@
std::vector<std::string> writepid_files_;
+ std::vector<std::string> task_profiles_;
+
std::set<std::string> interfaces_; // e.g. some.package.foo@1.0::IBaz/instance-name
// keycodes for triggering this service via /dev/input/input*
diff --git a/init/service_parser.cpp b/init/service_parser.cpp
index 560f693..1444258 100644
--- a/init/service_parser.cpp
+++ b/init/service_parser.cpp
@@ -360,6 +360,12 @@
return Error() << "Invalid shutdown option";
}
+Result<void> ServiceParser::ParseTaskProfiles(std::vector<std::string>&& args) {
+ args.erase(args.begin());
+ service_->task_profiles_ = std::move(args);
+ return {};
+}
+
Result<void> ServiceParser::ParseTimeoutPeriod(std::vector<std::string>&& args) {
int period;
if (!ParseInt(args[1], &period, 1)) {
@@ -529,6 +535,7 @@
{"sigstop", {0, 0, &ServiceParser::ParseSigstop}},
{"socket", {3, 6, &ServiceParser::ParseSocket}},
{"stdio_to_kmsg", {0, 0, &ServiceParser::ParseStdioToKmsg}},
+ {"task_profiles", {1, kMax, &ServiceParser::ParseTaskProfiles}},
{"timeout_period", {1, 1, &ServiceParser::ParseTimeoutPeriod}},
{"updatable", {0, 0, &ServiceParser::ParseUpdatable}},
{"user", {1, 1, &ServiceParser::ParseUser}},
diff --git a/init/service_parser.h b/init/service_parser.h
index 7bb0cc0..0fd2da5 100644
--- a/init/service_parser.h
+++ b/init/service_parser.h
@@ -78,6 +78,7 @@
Result<void> ParseSigstop(std::vector<std::string>&& args);
Result<void> ParseSocket(std::vector<std::string>&& args);
Result<void> ParseStdioToKmsg(std::vector<std::string>&& args);
+ Result<void> ParseTaskProfiles(std::vector<std::string>&& args);
Result<void> ParseTimeoutPeriod(std::vector<std::string>&& args);
Result<void> ParseFile(std::vector<std::string>&& args);
Result<void> ParseUser(std::vector<std::string>&& args);