diff --git a/libprocessgroup/cgrouprc/include/android/cgrouprc.h b/libprocessgroup/cgrouprc/include/android/cgrouprc.h index 9a799547d..100d60ea9 100644 --- a/libprocessgroup/cgrouprc/include/android/cgrouprc.h +++ b/libprocessgroup/cgrouprc/include/android/cgrouprc.h @@ -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. diff --git a/libprocessgroup/profiles/cgroups.json b/libprocessgroup/profiles/cgroups.json index 962d2baa8..063422091 100644 --- a/libprocessgroup/profiles/cgroups.json +++ b/libprocessgroup/profiles/cgroups.json @@ -26,7 +26,8 @@ "Path": "/dev/memcg", "Mode": "0700", "UID": "root", - "GID": "system" + "GID": "system", + "Optional": true } ], "Cgroups2": { diff --git a/libprocessgroup/profiles/cgroups.proto b/libprocessgroup/profiles/cgroups.proto index 13adcae07..f2de3452a 100644 --- a/libprocessgroup/profiles/cgroups.proto +++ b/libprocessgroup/profiles/cgroups.proto @@ -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 diff --git a/libprocessgroup/profiles/cgroups_30.json b/libprocessgroup/profiles/cgroups_30.json index 17d492949..80a074bf1 100644 --- a/libprocessgroup/profiles/cgroups_30.json +++ b/libprocessgroup/profiles/cgroups_30.json @@ -5,7 +5,8 @@ "Path": "/dev/stune", "Mode": "0755", "UID": "system", - "GID": "system" + "GID": "system", + "Optional": true } ] } diff --git a/libprocessgroup/setup/cgroup_map_write.cpp b/libprocessgroup/setup/cgroup_map_write.cpp index b0b91f81f..3121d244b 100644 --- a/libprocessgroup/setup/cgroup_map_write.cpp +++ b/libprocessgroup/setup/cgroup_map_write.cpp @@ -161,6 +161,10 @@ static void MergeCgroupToDescriptors(std::map* 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;