libprocessgroup: introduce optional attribute for cgroup controllers

Memory cgroup controller is not used by high-end Android devices and is
disabled in Android kernels 5.10+, however Android Go devices still
require this controller.
Similarly schedtune controller is being replaced with cpu controller's
utilclamp feature, however some devices are using older kernels which
only support schedtune.
To prevent spamming logcat with errors we need a way to mark a
controller optional in such cases without removing it from
cgroups.json file.
Introduce "Optional" attribute to cgroup controller's cgroups.json
description to accomodate these cases. When an optional controller
fails to mount due to lack of support in the kernel it will log an
informational message without generating further errors.

Bug: 181866655
Test: boot and observe libprocessgroup messages in logcat
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Change-Id: Ib5bcfdd8d338704f3f9d8b326d8ddd88b67915a1
This commit is contained in:
Suren Baghdasaryan 2021-03-10 10:31:35 -08:00
parent c19a7dd30e
commit 7f19b1e6de
5 changed files with 20 additions and 5 deletions

View file

@ -68,6 +68,7 @@ __attribute__((warn_unused_result)) uint32_t ACgroupController_getVersion(const
*/
#define CGROUPRC_CONTROLLER_FLAG_MOUNTED 0x1
#define CGROUPRC_CONTROLLER_FLAG_NEEDS_ACTIVATION 0x2
#define CGROUPRC_CONTROLLER_FLAG_OPTIONAL 0x4
/**
* Returns the flags bitmask of the given controller.

View file

@ -26,7 +26,8 @@
"Path": "/dev/memcg",
"Mode": "0700",
"UID": "root",
"GID": "system"
"GID": "system",
"Optional": true
}
],
"Cgroups2": {

View file

@ -24,7 +24,7 @@ message Cgroups {
Cgroups2 cgroups2 = 2 [json_name = "Cgroups2"];
}
// Next: 7
// Next: 8
message Cgroup {
string controller = 1 [json_name = "Controller"];
string path = 2 [json_name = "Path"];
@ -35,6 +35,7 @@ message Cgroup {
// when a boolean is specified as false, so leave unspecified in that case
// https://developers.google.com/protocol-buffers/docs/proto3#default
bool needs_activation = 6 [json_name = "NeedsActivation"];
bool is_optional = 7 [json_name = "Optional"];
}
// Next: 6

View file

@ -5,7 +5,8 @@
"Path": "/dev/stune",
"Mode": "0755",
"UID": "system",
"GID": "system"
"GID": "system",
"Optional": true
}
]
}

View file

@ -161,6 +161,10 @@ static void MergeCgroupToDescriptors(std::map<std::string, CgroupDescriptor>* de
controller_flags |= CGROUPRC_CONTROLLER_FLAG_NEEDS_ACTIVATION;
}
if (cgroup["Optional"].isBool() && cgroup["Optional"].asBool()) {
controller_flags |= CGROUPRC_CONTROLLER_FLAG_OPTIONAL;
}
CgroupDescriptor descriptor(
cgroups_version, name, path, std::strtoul(cgroup["Mode"].asString().c_str(), 0, 8),
cgroup["UID"].asString(), cgroup["GID"].asString(), controller_flags);
@ -308,8 +312,15 @@ static bool SetupCgroup(const CgroupDescriptor& descriptor) {
}
if (result < 0) {
PLOG(ERROR) << "Failed to mount " << controller->name() << " cgroup";
return false;
bool optional = controller->flags() & CGROUPRC_CONTROLLER_FLAG_OPTIONAL;
if (optional && errno == EINVAL) {
// Optional controllers are allowed to fail to mount if kernel does not support them
LOG(INFO) << "Optional " << controller->name() << " cgroup controller is not mounted";
} else {
PLOG(ERROR) << "Failed to mount " << controller->name() << " cgroup";
return false;
}
}
return true;