diff --git a/init/readme.txt b/init/readme.txt index aa372eb92..8130806c2 100644 --- a/init/readme.txt +++ b/init/readme.txt @@ -184,6 +184,9 @@ writepid Write the child's pid to the given files when it forks. Meant for cgroup/cpuset usage. +priority + Scheduling priority of the service process. This value has to be in range + -20 to 19. Default priority is 0. Priority is set via setpriority(). Triggers -------- diff --git a/init/service.cpp b/init/service.cpp index 4175d054f..4ea8936d7 100644 --- a/init/service.cpp +++ b/init/service.cpp @@ -17,7 +17,9 @@ #include "service.h" #include +#include #include +#include #include #include #include @@ -29,6 +31,7 @@ #include #include #include +#include #include @@ -65,7 +68,7 @@ Service::Service(const std::string& name, const std::string& classname, const std::vector& args) : name_(name), classname_(classname), flags_(0), pid_(0), time_started_(0), time_crashed_(0), nr_crashed_(0), uid_(0), gid_(0), seclabel_(""), - ioprio_class_(IoSchedClass_NONE), ioprio_pri_(0), args_(args) { + ioprio_class_(IoSchedClass_NONE), ioprio_pri_(0), priority_(0), args_(args) { onrestart_.InitSingleTrigger("onrestart"); } @@ -74,7 +77,8 @@ Service::Service(const std::string& name, const std::string& classname, const std::string& seclabel, const std::vector& args) : name_(name), classname_(classname), flags_(flags), pid_(0), time_started_(0), time_crashed_(0), nr_crashed_(0), uid_(uid), gid_(gid), supp_gids_(supp_gids), - seclabel_(seclabel), ioprio_class_(IoSchedClass_NONE), ioprio_pri_(0), args_(args) { + seclabel_(seclabel), ioprio_class_(IoSchedClass_NONE), ioprio_pri_(0), priority_(0), + args_(args) { onrestart_.InitSingleTrigger("onrestart"); } @@ -197,6 +201,19 @@ bool Service::HandleGroup(const std::vector& args, std::string* err return true; } +bool Service::HandlePriority(const std::vector& args, std::string* err) { + priority_ = std::stoi(args[1]); + + if (priority_ < ANDROID_PRIORITY_HIGHEST || priority_ > ANDROID_PRIORITY_LOWEST) { + priority_ = 0; + *err = StringPrintf("process priority value must be range %d - %d", + ANDROID_PRIORITY_HIGHEST, ANDROID_PRIORITY_LOWEST); + return false; + } + + return true; +} + bool Service::HandleIoprio(const std::vector& args, std::string* err) { ioprio_pri_ = std::stoul(args[2], 0, 8); @@ -290,6 +307,7 @@ Service::OptionHandlerMap::Map& Service::OptionHandlerMap::map() const { {"disabled", {0, 0, &Service::HandleDisabled}}, {"group", {1, NR_SVC_SUPP_GIDS + 1, &Service::HandleGroup}}, {"ioprio", {2, 2, &Service::HandleIoprio}}, + {"priority", {1, 1, &Service::HandlePriority}}, {"keycodes", {1, kMax, &Service::HandleKeycodes}}, {"oneshot", {0, 0, &Service::HandleOneshot}}, {"onrestart", {1, kMax, &Service::HandleOnrestart}}, @@ -470,6 +488,12 @@ bool Service::Start() { _exit(127); } } + if (priority_ != 0) { + if (setpriority(PRIO_PROCESS, 0, priority_) != 0) { + ERROR("setpriority failed: %s\n", strerror(errno)); + _exit(127); + } + } std::vector strs; for (const auto& s : args_) { diff --git a/init/service.h b/init/service.h index d6ce664c9..dc14f9a84 100644 --- a/init/service.h +++ b/init/service.h @@ -93,6 +93,7 @@ public: pid_t pid() const { return pid_; } uid_t uid() const { return uid_; } gid_t gid() const { return gid_; } + int priority() const { return priority_; } const std::vector& supp_gids() const { return supp_gids_; } const std::string& seclabel() const { return seclabel_; } const std::vector& keycodes() const { return keycodes_; } @@ -116,6 +117,7 @@ private: bool HandleCritical(const std::vector& args, std::string* err); bool HandleDisabled(const std::vector& args, std::string* err); bool HandleGroup(const std::vector& args, std::string* err); + bool HandlePriority(const std::vector& args, std::string* err); bool HandleIoprio(const std::vector& args, std::string* err); bool HandleKeycodes(const std::vector& args, std::string* err); bool HandleOneshot(const std::vector& args, std::string* err); @@ -155,6 +157,7 @@ private: IoSchedClass ioprio_class_; int ioprio_pri_; + int priority_; std::vector args_; };