Add build flag to split the cgroup v2 hierarchy into apps/system
This flag adds "apps" and "system" cgroups underneath the v2 hierarchy root. Cgroups with UIDs < 10000 (AID_APP_START) will be placed under "system" and others will be placed under "apps". UIDs under 10000 are reserved for core Android subsystems. This allows us to apply different cgroup controls collectively to system processes and normal applications. Bug: 327480673 Change-Id: I40837dee27a59691f81fef48e66a86c5eacda892
This commit is contained in:
parent
f8901767e6
commit
1cfa2c4111
4 changed files with 77 additions and 0 deletions
|
@ -8,6 +8,7 @@ soong_config_module_type {
|
|||
config_namespace: "ANDROID",
|
||||
bool_variables: [
|
||||
"memcg_v2_force_enabled",
|
||||
"cgroup_v2_sys_app_isolation",
|
||||
],
|
||||
properties: [
|
||||
"cflags",
|
||||
|
@ -23,6 +24,11 @@ libprocessgroup_flag_aware_cc_defaults {
|
|||
"-DMEMCG_V2_FORCE_ENABLED=true",
|
||||
],
|
||||
},
|
||||
cgroup_v2_sys_app_isolation: {
|
||||
cflags: [
|
||||
"-DCGROUP_V2_SYS_APP_ISOLATION=true",
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -20,10 +20,18 @@
|
|||
#define MEMCG_V2_FORCE_ENABLED false
|
||||
#endif
|
||||
|
||||
#ifndef CGROUP_V2_SYS_APP_ISOLATION
|
||||
#define CGROUP_V2_SYS_APP_ISOLATION false
|
||||
#endif
|
||||
|
||||
namespace android::libprocessgroup_flags {
|
||||
|
||||
inline consteval bool force_memcg_v2() {
|
||||
return MEMCG_V2_FORCE_ENABLED;
|
||||
}
|
||||
|
||||
inline consteval bool cgroup_v2_sys_app_isolation() {
|
||||
return CGROUP_V2_SYS_APP_ISOLATION;
|
||||
}
|
||||
|
||||
} // namespace android::libprocessgroup_flags
|
||||
|
|
|
@ -483,6 +483,42 @@ static std::optional<bool> MEMCGDisabled(
|
|||
return content.find("memory") == std::string::npos;
|
||||
}
|
||||
|
||||
static bool CreateV2SubHierarchy(
|
||||
const std::string& path,
|
||||
const std::map<std::string, android::cgrouprc::CgroupDescriptor>& descriptors) {
|
||||
using namespace android::cgrouprc;
|
||||
|
||||
const auto cgv2_iter = descriptors.find(CGROUPV2_HIERARCHY_NAME);
|
||||
if (cgv2_iter == descriptors.end()) return false;
|
||||
const android::cgrouprc::CgroupDescriptor cgv2_descriptor = cgv2_iter->second;
|
||||
|
||||
if (!Mkdir(path, cgv2_descriptor.mode(), cgv2_descriptor.uid(), cgv2_descriptor.gid())) {
|
||||
PLOG(ERROR) << "Failed to create directory for " << path;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Activate all v2 controllers in path so they can be activated in
|
||||
// children as they are created.
|
||||
for (const auto& [name, descriptor] : descriptors) {
|
||||
const format::CgroupController* controller = descriptor.controller();
|
||||
std::uint32_t flags = controller->flags();
|
||||
if (controller->version() == 2 && name != CGROUPV2_HIERARCHY_NAME &&
|
||||
flags & CGROUPRC_CONTROLLER_FLAG_NEEDS_ACTIVATION) {
|
||||
std::string str("+");
|
||||
str += controller->name();
|
||||
if (!android::base::WriteStringToFile(str, path + "/cgroup.subtree_control")) {
|
||||
if (flags & CGROUPRC_CONTROLLER_FLAG_OPTIONAL) {
|
||||
PLOG(WARNING) << "Activation of cgroup controller " << str << " failed in path "
|
||||
<< path;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CgroupSetup() {
|
||||
using namespace android::cgrouprc;
|
||||
|
||||
|
@ -527,6 +563,21 @@ bool CgroupSetup() {
|
|||
}
|
||||
}
|
||||
|
||||
// System / app isolation.
|
||||
// This really belongs in early-init in init.rc, but we cannot use the flag there.
|
||||
if (android::libprocessgroup_flags::cgroup_v2_sys_app_isolation()) {
|
||||
const auto it = descriptors.find(CGROUPV2_HIERARCHY_NAME);
|
||||
const std::string cgroup_v2_root = (it == descriptors.end())
|
||||
? CGROUP_V2_ROOT_DEFAULT
|
||||
: it->second.controller()->path();
|
||||
|
||||
LOG(INFO) << "Using system/app isolation under: " << cgroup_v2_root;
|
||||
if (!CreateV2SubHierarchy(cgroup_v2_root + "/apps", descriptors) ||
|
||||
!CreateV2SubHierarchy(cgroup_v2_root + "/system", descriptors)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// mkdir <CGROUPS_RC_DIR> 0711 system system
|
||||
if (!Mkdir(android::base::Dirname(CGROUPS_RC_PATH), 0711, "system", "system")) {
|
||||
LOG(ERROR) << "Failed to create directory for " << CGROUPS_RC_PATH << " file";
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include <json/reader.h>
|
||||
#include <json/value.h>
|
||||
|
||||
#include <build_flags.h>
|
||||
|
||||
// To avoid issues in sdk_mac build
|
||||
#if defined(__ANDROID__)
|
||||
#include <sys/prctl.h>
|
||||
|
@ -126,7 +128,17 @@ void ProfileAttribute::Reset(const CgroupController& controller, const std::stri
|
|||
file_v2_name_ = file_v2_name;
|
||||
}
|
||||
|
||||
static bool isSystemApp(uid_t uid) {
|
||||
return uid < AID_APP_START;
|
||||
}
|
||||
|
||||
std::string ConvertUidToPath(const char* root_cgroup_path, uid_t uid) {
|
||||
if (android::libprocessgroup_flags::cgroup_v2_sys_app_isolation()) {
|
||||
if (isSystemApp(uid))
|
||||
return StringPrintf("%s/system/uid_%u", root_cgroup_path, uid);
|
||||
else
|
||||
return StringPrintf("%s/apps/uid_%u", root_cgroup_path, uid);
|
||||
}
|
||||
return StringPrintf("%s/uid_%u", root_cgroup_path, uid);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue