Skip to content

more ergonomic parent/child cgroups #142

@gtrak

Description

@gtrak

Is your feature request related to a problem? Please describe.
I couldn't find a direct way to create a parent cgroup, which was required for threaded cgroups to work properly. This was my first experience using cgroups, and it was mostly smooth besides this issue. Without the parent/child relationship, I got a 'operation not supported' error when writing to cgroup.threads, and tracked it down to this requirement with some help from ChatGPT.

The official docs say:

Once threaded, the cgroup can’t be made a domain again. To enable the thread mode, the following conditions must be met. As the cgroup will join the parent’s resource domain. The parent must either be a valid (threaded) domain or a threaded cgroup.

Initially, I just created the final cgroup off the root, which isn't a threaded parent.

Describe the solution you'd like
A more intentional and discoverable method to do what I did.

Describe alternatives you've considered
It could be covered in documentation or tests.

Additional context
Sample code of my work around:

// You can't actually control threads in subprocesses unless there's a threaded parent cgroup
    let parent_cgroup = CgroupBuilder::new("load_test_parent").build(hierarchies::auto())?;

    parent_cgroup
        .set_cgroup_type(cgroup::CGROUP_MODE_THREADED)
        .expect("Failed to set Threaded mode");

    // This is the part I think could be more ergonomic
    let child = "load_test_parent/".to_owned() + cgroup_name;

    let cgroup = CgroupBuilder::new(child.as_str())
        .cpu()
        .cpus("0-3".to_owned())
        .done()
        .pid()
        .maximum_number_of_processes(MaxValue::Value(thread_limit))
        .done()
        .build(hierarchies::auto())?;

    cgroup
        .set_cgroup_type(cgroup::CGROUP_MODE_THREADED)
        .expect("Failed to set Threaded mode");

    // Start subprocess within the cgroup
    let subprocess = Command::new("mycommand")
        .args(&["-v"])
        .spawn()
        .expect("Failed to start subprocess");

    // These add_task functions were also unclear from looking at the impls. 
    // The parent group should receive the pid to cgroup.procs, and the child should receive it to cgroup.threads. 
    // If I do add_task here, I get 'Operation not supported'.
    parent_cgroup
        .add_task_by_tgid(CgroupPid::from(&subprocess))
        .expect("Failed to add subprocess to parent cgroup");

    cgroup
        .add_task(CgroupPid::from(&subprocess))
        .expect("Failed to add Jetty process threads to child cgroup");

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions