Merge "Add memcg related configs to init."
am: b84666cbc0
Change-Id: I437c5d05582c6a3cce632f92835ee91f419a7190
This commit is contained in:
commit
7564622f88
5 changed files with 111 additions and 13 deletions
|
@ -260,6 +260,18 @@ runs the service.
|
|||
> Sets the child's /proc/self/oom\_score\_adj to the specified value,
|
||||
which must range from -1000 to 1000.
|
||||
|
||||
`memcg.swappiness <value>`
|
||||
> Sets the child's memory.swappiness to the specified value (only if memcg is mounted),
|
||||
which must be equal or greater than 0.
|
||||
|
||||
`memcg.soft_limit_in_bytes <value>`
|
||||
> Sets the child's memory.soft_limit_in_bytes to the specified value (only if memcg is mounted),
|
||||
which must be equal or greater than 0.
|
||||
|
||||
`memcg.limit_in_bytes <value>`
|
||||
> Sets the child's memory.limit_in_bytes to the specified value (only if memcg is mounted),
|
||||
which must be equal or greater than 0.
|
||||
|
||||
`shutdown <shutdown_behavior>`
|
||||
> Set shutdown behavior of the service process. When this is not specified,
|
||||
the service is killed during shutdown process by using SIGTERM and SIGKILL.
|
||||
|
|
|
@ -171,6 +171,9 @@ Service::Service(const std::string& name, const std::vector<std::string>& args)
|
|||
ioprio_pri_(0),
|
||||
priority_(0),
|
||||
oom_score_adjust_(-1000),
|
||||
swappiness_(-1),
|
||||
soft_limit_in_bytes_(-1),
|
||||
limit_in_bytes_(-1),
|
||||
args_(args) {
|
||||
onrestart_.InitSingleTrigger("onrestart");
|
||||
}
|
||||
|
@ -196,6 +199,9 @@ Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
|
|||
ioprio_pri_(0),
|
||||
priority_(0),
|
||||
oom_score_adjust_(-1000),
|
||||
swappiness_(-1),
|
||||
soft_limit_in_bytes_(-1),
|
||||
limit_in_bytes_(-1),
|
||||
args_(args) {
|
||||
onrestart_.InitSingleTrigger("onrestart");
|
||||
}
|
||||
|
@ -491,6 +497,30 @@ bool Service::ParseOomScoreAdjust(const std::vector<std::string>& args, std::str
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Service::ParseMemcgSwappiness(const std::vector<std::string>& args, std::string* err) {
|
||||
if (!ParseInt(args[1], &swappiness_, 0)) {
|
||||
*err = "swappiness value must be equal or greater than 0";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Service::ParseMemcgLimitInBytes(const std::vector<std::string>& args, std::string* err) {
|
||||
if (!ParseInt(args[1], &limit_in_bytes_, 0)) {
|
||||
*err = "limit_in_bytes value must be equal or greater than 0";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Service::ParseMemcgSoftLimitInBytes(const std::vector<std::string>& args, std::string* err) {
|
||||
if (!ParseInt(args[1], &soft_limit_in_bytes_, 0)) {
|
||||
*err = "soft_limit_in_bytes value must be equal or greater than 0";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Service::ParseSeclabel(const std::vector<std::string>& args, std::string* err) {
|
||||
seclabel_ = args[1];
|
||||
return true;
|
||||
|
@ -609,6 +639,12 @@ const Service::OptionParserMap::Map& Service::OptionParserMap::map() const {
|
|||
{"onrestart", {1, kMax, &Service::ParseOnrestart}},
|
||||
{"oom_score_adjust",
|
||||
{1, 1, &Service::ParseOomScoreAdjust}},
|
||||
{"memcg.swappiness",
|
||||
{1, 1, &Service::ParseMemcgSwappiness}},
|
||||
{"memcg.soft_limit_in_bytes",
|
||||
{1, 1, &Service::ParseMemcgSoftLimitInBytes}},
|
||||
{"memcg.limit_in_bytes",
|
||||
{1, 1, &Service::ParseMemcgLimitInBytes}},
|
||||
{"namespace", {1, 2, &Service::ParseNamespace}},
|
||||
{"seclabel", {1, 1, &Service::ParseSeclabel}},
|
||||
{"setenv", {2, 2, &Service::ParseSetenv}},
|
||||
|
@ -795,6 +831,24 @@ bool Service::Start() {
|
|||
if (errno != 0) {
|
||||
PLOG(ERROR) << "createProcessGroup(" << uid_ << ", " << pid_ << ") failed for service '"
|
||||
<< name_ << "'";
|
||||
} else {
|
||||
if (swappiness_ != -1) {
|
||||
if (!setProcessGroupSwappiness(uid_, pid_, swappiness_)) {
|
||||
PLOG(ERROR) << "setProcessGroupSwappiness failed";
|
||||
}
|
||||
}
|
||||
|
||||
if (soft_limit_in_bytes_ != -1) {
|
||||
if (!setProcessGroupSoftLimit(uid_, pid_, soft_limit_in_bytes_)) {
|
||||
PLOG(ERROR) << "setProcessGroupSoftLimit failed";
|
||||
}
|
||||
}
|
||||
|
||||
if (limit_in_bytes_ != -1) {
|
||||
if (!setProcessGroupLimit(uid_, pid_, limit_in_bytes_)) {
|
||||
PLOG(ERROR) << "setProcessGroupLimit failed";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags_ & SVC_EXEC) != 0) {
|
||||
|
|
|
@ -134,6 +134,9 @@ class Service {
|
|||
bool ParseOneshot(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseOnrestart(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseOomScoreAdjust(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseMemcgLimitInBytes(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseMemcgSoftLimitInBytes(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseMemcgSwappiness(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseNamespace(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseSeclabel(const std::vector<std::string>& args, std::string* err);
|
||||
bool ParseSetenv(const std::vector<std::string>& args, std::string* err);
|
||||
|
@ -181,6 +184,10 @@ class Service {
|
|||
|
||||
int oom_score_adjust_;
|
||||
|
||||
int swappiness_;
|
||||
int soft_limit_in_bytes_;
|
||||
int limit_in_bytes_;
|
||||
|
||||
bool process_cgroup_empty_ = false;
|
||||
|
||||
std::vector<std::string> args_;
|
||||
|
|
|
@ -33,6 +33,10 @@ int killProcessGroupOnce(uid_t uid, int initialPid, int signal);
|
|||
|
||||
int createProcessGroup(uid_t uid, int initialPid);
|
||||
|
||||
bool setProcessGroupSwappiness(uid_t uid, int initialPid, int swappiness);
|
||||
bool setProcessGroupSoftLimit(uid_t uid, int initialPid, int64_t softLimitInBytes);
|
||||
bool setProcessGroupLimit(uid_t uid, int initialPid, int64_t limitInBytes);
|
||||
|
||||
void removeAllProcessGroups(void);
|
||||
|
||||
__END_DECLS
|
||||
|
|
|
@ -35,12 +35,15 @@
|
|||
#include <set>
|
||||
#include <thread>
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <private/android_filesystem_config.h>
|
||||
|
||||
#include <processgroup/processgroup.h>
|
||||
|
||||
using android::base::WriteStringToFile;
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
#define MEM_CGROUP_PATH "/dev/memcg/apps"
|
||||
|
@ -402,22 +405,40 @@ int createProcessGroup(uid_t uid, int initialPid)
|
|||
|
||||
strlcat(path, PROCESSGROUP_CGROUP_PROCS_FILE, sizeof(path));
|
||||
|
||||
int fd = open(path, O_WRONLY);
|
||||
if (fd == -1) {
|
||||
int ret = -errno;
|
||||
PLOG(ERROR) << "Failed to open " << path;
|
||||
return ret;
|
||||
}
|
||||
|
||||
char pid[PROCESSGROUP_MAX_PID_LEN + 1] = {0};
|
||||
int len = snprintf(pid, sizeof(pid), "%d", initialPid);
|
||||
|
||||
int ret = 0;
|
||||
if (write(fd, pid, len) < 0) {
|
||||
if (!WriteStringToFile(std::to_string(initialPid), path)) {
|
||||
ret = -errno;
|
||||
PLOG(ERROR) << "Failed to write '" << pid << "' to " << path;
|
||||
PLOG(ERROR) << "Failed to write '" << initialPid << "' to " << path;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool setProcessGroupValue(uid_t uid, int pid, const char* fileName, int64_t value) {
|
||||
char path[PROCESSGROUP_MAX_PATH_LEN] = {0};
|
||||
if (strcmp(getCgroupRootPath(), MEM_CGROUP_PATH)) {
|
||||
PLOG(ERROR) << "Memcg is not mounted." << path;
|
||||
return false;
|
||||
}
|
||||
|
||||
convertUidPidToPath(path, sizeof(path), uid, pid);
|
||||
strlcat(path, fileName, sizeof(path));
|
||||
|
||||
if (!WriteStringToFile(std::to_string(value), path)) {
|
||||
PLOG(ERROR) << "Failed to write '" << value << "' to " << path;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool setProcessGroupSwappiness(uid_t uid, int pid, int swappiness) {
|
||||
return setProcessGroupValue(uid, pid, "/memory.swappiness", swappiness);
|
||||
}
|
||||
|
||||
bool setProcessGroupSoftLimit(uid_t uid, int pid, int64_t soft_limit_in_bytes) {
|
||||
return setProcessGroupValue(uid, pid, "/memory.soft_limit_in_bytes", soft_limit_in_bytes);
|
||||
}
|
||||
|
||||
bool setProcessGroupLimit(uid_t uid, int pid, int64_t limit_in_bytes) {
|
||||
return setProcessGroupValue(uid, pid, "/memory.limit_in_bytes", limit_in_bytes);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue