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 This is mutually exclusive with the console option, which additionally connects stdin to the
given console. 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>` `timeout_period <seconds>`
> Provide a timeout after which point the service will be killed. The oneshot keyword is respected > 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. 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 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. 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. '/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 Triggers

View file

@ -511,6 +511,10 @@ Result<void> Service::Start() {
LOG(ERROR) << "failed to write pid to files: " << result.error(); 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 // As requested, set our gid, supplemental gids, uid, context, and
// priority. Aborts on failure. // priority. Aborts on failure.
SetProcessAttributesAndCaps(); SetProcessAttributesAndCaps();

View file

@ -170,6 +170,8 @@ class Service {
std::vector<std::string> writepid_files_; 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 std::set<std::string> interfaces_; // e.g. some.package.foo@1.0::IBaz/instance-name
// keycodes for triggering this service via /dev/input/input* // 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"; 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) { Result<void> ServiceParser::ParseTimeoutPeriod(std::vector<std::string>&& args) {
int period; int period;
if (!ParseInt(args[1], &period, 1)) { if (!ParseInt(args[1], &period, 1)) {
@ -529,6 +535,7 @@ const KeywordMap<ServiceParser::OptionParser>& ServiceParser::GetParserMap() con
{"sigstop", {0, 0, &ServiceParser::ParseSigstop}}, {"sigstop", {0, 0, &ServiceParser::ParseSigstop}},
{"socket", {3, 6, &ServiceParser::ParseSocket}}, {"socket", {3, 6, &ServiceParser::ParseSocket}},
{"stdio_to_kmsg", {0, 0, &ServiceParser::ParseStdioToKmsg}}, {"stdio_to_kmsg", {0, 0, &ServiceParser::ParseStdioToKmsg}},
{"task_profiles", {1, kMax, &ServiceParser::ParseTaskProfiles}},
{"timeout_period", {1, 1, &ServiceParser::ParseTimeoutPeriod}}, {"timeout_period", {1, 1, &ServiceParser::ParseTimeoutPeriod}},
{"updatable", {0, 0, &ServiceParser::ParseUpdatable}}, {"updatable", {0, 0, &ServiceParser::ParseUpdatable}},
{"user", {1, 1, &ServiceParser::ParseUser}}, {"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> ParseSigstop(std::vector<std::string>&& args);
Result<void> ParseSocket(std::vector<std::string>&& args); Result<void> ParseSocket(std::vector<std::string>&& args);
Result<void> ParseStdioToKmsg(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> ParseTimeoutPeriod(std::vector<std::string>&& args);
Result<void> ParseFile(std::vector<std::string>&& args); Result<void> ParseFile(std::vector<std::string>&& args);
Result<void> ParseUser(std::vector<std::string>&& args); Result<void> ParseUser(std::vector<std::string>&& args);