libprocessgroup: Activate controllers in cgroup v2 hierarchy at intermediate levels
When creating uid/pid hierarchy, cgroup.subtree_control should be set at every level of that hierarchy except for the leaf level. Bug: 195149205 Signed-off-by: Suren Baghdasaryan <surenb@google.com> Change-Id: Iedc2e859715b31db62158c85016708f252db2b70
This commit is contained in:
parent
18a9324e3f
commit
25ad3f9b86
3 changed files with 32 additions and 4 deletions
|
@ -43,6 +43,7 @@
|
|||
using android::base::GetBoolProperty;
|
||||
using android::base::StringPrintf;
|
||||
using android::base::unique_fd;
|
||||
using android::base::WriteStringToFile;
|
||||
|
||||
static constexpr const char* CGROUP_PROCS_FILE = "/cgroup.procs";
|
||||
static constexpr const char* CGROUP_TASKS_FILE = "/tasks";
|
||||
|
@ -202,3 +203,21 @@ CgroupController CgroupMap::FindController(const std::string& name) const {
|
|||
|
||||
return CgroupController(nullptr);
|
||||
}
|
||||
|
||||
int CgroupMap::ActivateControllers(const std::string& path) const {
|
||||
if (__builtin_available(android 30, *)) {
|
||||
auto controller_count = ACgroupFile_getControllerCount();
|
||||
for (uint32_t i = 0; i < controller_count; ++i) {
|
||||
const ACgroupController* controller = ACgroupFile_getController(i);
|
||||
if (ACgroupController_getFlags(controller) &
|
||||
CGROUPRC_CONTROLLER_FLAG_NEEDS_ACTIVATION) {
|
||||
std::string str = std::string("+") + ACgroupController_getName(controller);
|
||||
if (!WriteStringToFile(str, path + "/cgroup.subtree_control")) {
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ class CgroupMap {
|
|||
|
||||
static CgroupMap& GetInstance();
|
||||
CgroupController FindController(const std::string& name) const;
|
||||
int ActivateControllers(const std::string& path) const;
|
||||
|
||||
private:
|
||||
bool loaded_ = false;
|
||||
|
|
|
@ -416,13 +416,15 @@ int killProcessGroupOnce(uid_t uid, int initialPid, int signal, int* max_process
|
|||
return KillProcessGroup(uid, initialPid, signal, 0 /*retries*/, max_processes);
|
||||
}
|
||||
|
||||
static int createProcessGroupInternal(uid_t uid, int initialPid, std::string cgroup) {
|
||||
static int createProcessGroupInternal(uid_t uid, int initialPid, std::string cgroup,
|
||||
bool activate_controllers) {
|
||||
auto uid_path = ConvertUidToPath(cgroup.c_str(), uid);
|
||||
|
||||
struct stat cgroup_stat;
|
||||
mode_t cgroup_mode = 0750;
|
||||
gid_t cgroup_uid = AID_SYSTEM;
|
||||
uid_t cgroup_gid = AID_SYSTEM;
|
||||
int ret = 0;
|
||||
|
||||
if (stat(cgroup.c_str(), &cgroup_stat) == 1) {
|
||||
PLOG(ERROR) << "Failed to get stats for " << cgroup;
|
||||
|
@ -436,6 +438,13 @@ static int createProcessGroupInternal(uid_t uid, int initialPid, std::string cgr
|
|||
PLOG(ERROR) << "Failed to make and chown " << uid_path;
|
||||
return -errno;
|
||||
}
|
||||
if (activate_controllers) {
|
||||
ret = CgroupMap::GetInstance().ActivateControllers(uid_path);
|
||||
if (ret) {
|
||||
LOG(ERROR) << "Failed to activate controllers in " << uid_path;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
auto uid_pid_path = ConvertUidPidToPath(cgroup.c_str(), uid, initialPid);
|
||||
|
||||
|
@ -446,7 +455,6 @@ static int createProcessGroupInternal(uid_t uid, int initialPid, std::string cgr
|
|||
|
||||
auto uid_pid_procs_file = uid_pid_path + PROCESSGROUP_CGROUP_PROCS_FILE;
|
||||
|
||||
int ret = 0;
|
||||
if (!WriteStringToFile(std::to_string(initialPid), uid_pid_procs_file)) {
|
||||
ret = -errno;
|
||||
PLOG(ERROR) << "Failed to write '" << initialPid << "' to " << uid_pid_procs_file;
|
||||
|
@ -466,14 +474,14 @@ int createProcessGroup(uid_t uid, int initialPid, bool memControl) {
|
|||
if (isMemoryCgroupSupported() && UsePerAppMemcg()) {
|
||||
CgroupGetControllerPath("memory", &cgroup);
|
||||
cgroup += "/apps";
|
||||
int ret = createProcessGroupInternal(uid, initialPid, cgroup);
|
||||
int ret = createProcessGroupInternal(uid, initialPid, cgroup, false);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
CgroupGetControllerPath(CGROUPV2_CONTROLLER_NAME, &cgroup);
|
||||
return createProcessGroupInternal(uid, initialPid, cgroup);
|
||||
return createProcessGroupInternal(uid, initialPid, cgroup, true);
|
||||
}
|
||||
|
||||
static bool SetProcessGroupValue(int tid, const std::string& attr_name, int64_t value) {
|
||||
|
|
Loading…
Reference in a new issue