Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d35f56b1 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "libprocessgroup: Rework SetupCgroup()"

parents 1324002f 1ec6ec4f
Loading
Loading
Loading
Loading
+95 −68
Original line number Diff line number Diff line
@@ -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, "", "")) {
@@ -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";
@@ -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