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
Merged-In: I0add9c3b363a7cb1ea89778780896cae1c8a303c
This commit is contained in:
Suren Baghdasaryan 2020-04-30 11:58:39 -07:00
parent 67a92651a2
commit 21ae541691
5 changed files with 20 additions and 0 deletions

View file

@ -322,6 +322,10 @@ runs the service.
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 @@ runs the service.
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

View file

@ -511,6 +511,10 @@ Result<void> Service::Start() {
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();

View file

@ -170,6 +170,8 @@ class Service {
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*

View file

@ -360,6 +360,12 @@ Result<void> ServiceParser::ParseShutdown(std::vector<std::string>&& args) {
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 @@ const KeywordMap<ServiceParser::OptionParser>& ServiceParser::GetParserMap() con
{"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}},

View file

@ -78,6 +78,7 @@ class ServiceParser : public SectionParser {
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);