Loading libprocessgroup/setup/cgroup_map_write.cpp +95 −68 Original line number Diff line number Diff line Loading @@ -254,13 +254,13 @@ static bool ReadDescriptors(std::map<std::string, CgroupDescriptor>* descriptors // To avoid issues in sdk_mac build #if defined(__ANDROID__) static bool SetupCgroup(const CgroupDescriptor& descriptor) { static bool IsOptionalController(const format::CgroupController* controller) { return controller->flags() & CGROUPRC_CONTROLLER_FLAG_OPTIONAL; } static bool MountV2CgroupController(const CgroupDescriptor& descriptor) { const format::CgroupController* controller = descriptor.controller(); int result; if (controller->version() == 2) { result = 0; if (!strcmp(controller->name(), CGROUPV2_CONTROLLER_NAME)) { // /sys/fs/cgroup is created by cgroup2 with specific selinux permissions, // try to create again in case the mount point is changed if (!Mkdir(controller->path(), 0, "", "")) { Loading @@ -278,32 +278,50 @@ static bool SetupCgroup(const CgroupDescriptor& descriptor) { if (mount("none", controller->path(), "cgroup2", MS_NODEV | MS_NOEXEC | MS_NOSUID, nullptr) < 0) { PLOG(ERROR) << "Failed to mount cgroup v2"; return IsOptionalController(controller); } } // selinux permissions change after mounting, so it's ok to change mode and owner now if (!ChangeDirModeAndOwner(controller->path(), descriptor.mode(), descriptor.uid(), descriptor.gid())) { LOG(ERROR) << "Failed to create directory for " << controller->name() << " cgroup"; result = -1; PLOG(ERROR) << "Change of ownership or mode failed for controller " << controller->name(); return IsOptionalController(controller); } } else { return true; } static bool ActivateV2CgroupController(const CgroupDescriptor& descriptor) { const format::CgroupController* controller = descriptor.controller(); if (!Mkdir(controller->path(), descriptor.mode(), descriptor.uid(), descriptor.gid())) { LOG(ERROR) << "Failed to create directory for " << controller->name() << " cgroup"; return false; } if (controller->flags() & CGROUPRC_CONTROLLER_FLAG_NEEDS_ACTIVATION) { std::string str = std::string("+") + controller->name(); std::string path = std::string(controller->path()) + "/cgroup.subtree_control"; std::string str = "+"; str += controller->name(); std::string path = controller->path(); path += "/cgroup.subtree_control"; if (!base::WriteStringToFile(str, path)) { LOG(ERROR) << "Failed to activate controller " << controller->name(); if (IsOptionalController(controller)) { PLOG(INFO) << "Failed to activate optional controller " << controller->name(); return true; } PLOG(ERROR) << "Failed to activate controller " << controller->name(); return false; } } return true; } } else { static bool MountV1CgroupController(const CgroupDescriptor& descriptor) { const format::CgroupController* controller = descriptor.controller(); // mkdir <path> [mode] [owner] [group] if (!Mkdir(controller->path(), descriptor.mode(), descriptor.uid(), descriptor.gid())) { LOG(ERROR) << "Failed to create directory for " << controller->name() << " cgroup"; Loading @@ -315,30 +333,39 @@ static bool SetupCgroup(const CgroupDescriptor& descriptor) { // to be prepended with controller name. For example this way instead of // /dev/cpuset/cpuset.cpus the attribute becomes /dev/cpuset/cpus which is what // the system currently expects. int res; if (!strcmp(controller->name(), "cpuset")) { // mount cpuset none /dev/cpuset nodev noexec nosuid result = mount("none", controller->path(), controller->name(), res = mount("none", controller->path(), controller->name(), MS_NODEV | MS_NOEXEC | MS_NOSUID, nullptr); } else { // mount cgroup none <path> nodev noexec nosuid <controller> result = mount("none", controller->path(), "cgroup", MS_NODEV | MS_NOEXEC | MS_NOSUID, res = mount("none", controller->path(), "cgroup", MS_NODEV | MS_NOEXEC | MS_NOSUID, controller->name()); } if (res != 0) { if (IsOptionalController(controller)) { PLOG(INFO) << "Failed to mount optional controller " << controller->name(); return true; } PLOG(ERROR) << "Failed to mount controller " << controller->name(); return false; } return true; } if (result < 0) { bool optional = controller->flags() & CGROUPRC_CONTROLLER_FLAG_OPTIONAL; static bool SetupCgroup(const CgroupDescriptor& descriptor) { const format::CgroupController* controller = descriptor.controller(); 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"; if (controller->version() == 2) { if (!strcmp(controller->name(), CGROUPV2_CONTROLLER_NAME)) { return MountV2CgroupController(descriptor); } else { PLOG(ERROR) << "Failed to mount " << controller->name() << " cgroup"; return false; return ActivateV2CgroupController(descriptor); } } else { return MountV1CgroupController(descriptor); } return true; } #else Loading Loading
libprocessgroup/setup/cgroup_map_write.cpp +95 −68 Original line number Diff line number Diff line Loading @@ -254,13 +254,13 @@ static bool ReadDescriptors(std::map<std::string, CgroupDescriptor>* descriptors // To avoid issues in sdk_mac build #if defined(__ANDROID__) static bool SetupCgroup(const CgroupDescriptor& descriptor) { static bool IsOptionalController(const format::CgroupController* controller) { return controller->flags() & CGROUPRC_CONTROLLER_FLAG_OPTIONAL; } static bool MountV2CgroupController(const CgroupDescriptor& descriptor) { const format::CgroupController* controller = descriptor.controller(); int result; if (controller->version() == 2) { result = 0; if (!strcmp(controller->name(), CGROUPV2_CONTROLLER_NAME)) { // /sys/fs/cgroup is created by cgroup2 with specific selinux permissions, // try to create again in case the mount point is changed if (!Mkdir(controller->path(), 0, "", "")) { Loading @@ -278,32 +278,50 @@ static bool SetupCgroup(const CgroupDescriptor& descriptor) { if (mount("none", controller->path(), "cgroup2", MS_NODEV | MS_NOEXEC | MS_NOSUID, nullptr) < 0) { PLOG(ERROR) << "Failed to mount cgroup v2"; return IsOptionalController(controller); } } // selinux permissions change after mounting, so it's ok to change mode and owner now if (!ChangeDirModeAndOwner(controller->path(), descriptor.mode(), descriptor.uid(), descriptor.gid())) { LOG(ERROR) << "Failed to create directory for " << controller->name() << " cgroup"; result = -1; PLOG(ERROR) << "Change of ownership or mode failed for controller " << controller->name(); return IsOptionalController(controller); } } else { return true; } static bool ActivateV2CgroupController(const CgroupDescriptor& descriptor) { const format::CgroupController* controller = descriptor.controller(); if (!Mkdir(controller->path(), descriptor.mode(), descriptor.uid(), descriptor.gid())) { LOG(ERROR) << "Failed to create directory for " << controller->name() << " cgroup"; return false; } if (controller->flags() & CGROUPRC_CONTROLLER_FLAG_NEEDS_ACTIVATION) { std::string str = std::string("+") + controller->name(); std::string path = std::string(controller->path()) + "/cgroup.subtree_control"; std::string str = "+"; str += controller->name(); std::string path = controller->path(); path += "/cgroup.subtree_control"; if (!base::WriteStringToFile(str, path)) { LOG(ERROR) << "Failed to activate controller " << controller->name(); if (IsOptionalController(controller)) { PLOG(INFO) << "Failed to activate optional controller " << controller->name(); return true; } PLOG(ERROR) << "Failed to activate controller " << controller->name(); return false; } } return true; } } else { static bool MountV1CgroupController(const CgroupDescriptor& descriptor) { const format::CgroupController* controller = descriptor.controller(); // mkdir <path> [mode] [owner] [group] if (!Mkdir(controller->path(), descriptor.mode(), descriptor.uid(), descriptor.gid())) { LOG(ERROR) << "Failed to create directory for " << controller->name() << " cgroup"; Loading @@ -315,30 +333,39 @@ static bool SetupCgroup(const CgroupDescriptor& descriptor) { // to be prepended with controller name. For example this way instead of // /dev/cpuset/cpuset.cpus the attribute becomes /dev/cpuset/cpus which is what // the system currently expects. int res; if (!strcmp(controller->name(), "cpuset")) { // mount cpuset none /dev/cpuset nodev noexec nosuid result = mount("none", controller->path(), controller->name(), res = mount("none", controller->path(), controller->name(), MS_NODEV | MS_NOEXEC | MS_NOSUID, nullptr); } else { // mount cgroup none <path> nodev noexec nosuid <controller> result = mount("none", controller->path(), "cgroup", MS_NODEV | MS_NOEXEC | MS_NOSUID, res = mount("none", controller->path(), "cgroup", MS_NODEV | MS_NOEXEC | MS_NOSUID, controller->name()); } if (res != 0) { if (IsOptionalController(controller)) { PLOG(INFO) << "Failed to mount optional controller " << controller->name(); return true; } PLOG(ERROR) << "Failed to mount controller " << controller->name(); return false; } return true; } if (result < 0) { bool optional = controller->flags() & CGROUPRC_CONTROLLER_FLAG_OPTIONAL; static bool SetupCgroup(const CgroupDescriptor& descriptor) { const format::CgroupController* controller = descriptor.controller(); 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"; if (controller->version() == 2) { if (!strcmp(controller->name(), CGROUPV2_CONTROLLER_NAME)) { return MountV2CgroupController(descriptor); } else { PLOG(ERROR) << "Failed to mount " << controller->name() << " cgroup"; return false; return ActivateV2CgroupController(descriptor); } } else { return MountV1CgroupController(descriptor); } return true; } #else Loading