Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions libcontainer/cgroups/fs/apply_raw.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ func (m *Manager) Apply(pid int) (err error) {
if err := sys.Apply(d); err != nil {
return err
}

// TODO: Apply should, ideally, be reentrant or be broken up into a separate
// create and join phase so that the cgroup hierarchy for a container can be
// created then join consists of writing the process pids to cgroup.procs
Expand Down Expand Up @@ -289,8 +290,14 @@ func (raw *cgroupData) join(subsystem string) (string, error) {
if err != nil {
return "", err
}
if err := os.MkdirAll(path, 0755); err != nil {
return "", err
_, err = os.Stat(path)
if err != nil && os.IsNotExist(err) {
if err := os.MkdirAll(path, 0755); err != nil {
return "", err
}
} else if err == nil {
//cgroup exists, therefore join only
raw.config.ExternalCgroup = true
}
if err := writeFile(path, CgroupProcesses, strconv.Itoa(raw.pid)); err != nil {
return "", err
Expand Down
3 changes: 3 additions & 0 deletions libcontainer/cgroups/fs/devices.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ func (s *DevicesGroup) Apply(d *cgroupData) error {
}

func (s *DevicesGroup) Set(path string, cgroup *configs.Cgroup) error {
if cgroup.ExternalCgroup {
return nil
}
if !cgroup.AllowAllDevices {
if err := writeFile(path, "devices.deny", "a"); err != nil {
return err
Expand Down
2 changes: 2 additions & 0 deletions libcontainer/configs/cgroup_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const (

type Cgroup struct {
Name string `json:"name"`
// indicates that this is an externally passed, fully created cgroup
ExternalCgroup bool `json:"external_cgroup"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't have a bool for this. If there is a path passed, then we use it. Resource may or may not be empty.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mrunalp I removed it.


// name of parent cgroup or slice
Parent string `json:"parent"`
Expand Down
3 changes: 3 additions & 0 deletions spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,9 @@ func createCgroupConfig(name string, spec *specs.LinuxRuntimeSpec, devices []*co
if err != nil {
return nil, err
}
if spec.Linux.CgroupsPath != "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use a combination of parent and the name to derive the path. So, you need to handle the parent as well and make sure it is correct.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was like this before. We used path as Name in docker for cgroup-parent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, @LK4D4 @mrunalp and I have discussed this, and the current behavior in runc(if operator provides parent, it will append parent to Name) should be sufficient.

name = spec.Linux.CgroupsPath
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I don't understand your PR, why set cgroupsPath to name? cgroupsPath should be a relative or absolute path, not just a cgroup name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hqhq Cgroups path is expected to be a path relative to the cgroups mount: https://github.com/opencontainers/specs/blob/master/runtime_config_linux.go#L29

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ashahab-altiscale I think the problem here is name should not identify a cgroup, because it should just be the name, not the full path.
In the code, cgroup path can be affected by parent besides name, though it won't happen in real life for now because we only support parent for Docker and Docker don't use cgroupsPath. But that'll be tricky if we want to expand these features in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should remove parent as you and @LK4D4 discussed. CgroupsPath must not be a full path, but relative to cgroup mount on host. That's what I interpret from spec.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, since cgroupsPath does not support split hierarchy, would parent be ever different than what this line retrieves: https://github.com/opencontainers/runc/blob/master/spec.go#L436

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the confusing, here all cgroup path I mentioned are relative to cgroup mount point, and full path I meat absolute path including cgroup name, like /web/apache/apache1, here I think what name should be is apache1, not the entire /web/apache/apache1.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand now, thanks for explanation. However, this name can also be a
path, since it gets appended to the cgroup mount.
On Nov 18, 2015 12:16 AM, "Qiang Huang" [email protected] wrote:

In spec.go
#399 (comment):

@@ -438,6 +438,9 @@ func createCgroupConfig(name string, spec _specs.LinuxRuntimeSpec, devices []_co
if err != nil {
return nil, err
}

  • if spec.Linux.CgroupsPath != "" {
  •   name = spec.Linux.CgroupsPath
    
  • }

Sorry for the confusing, here all cgroup path I mentioned are relative to
cgroup mount point, and full path I meat absolute path including cgroup
name, like /web/apache/apache1, here I think what name should be is
apache1, not the entire /web/apache/apache1.


Reply to this email directly or view it on GitHub
https://github.com/opencontainers/runc/pull/399/files#r45170849.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hqhq I just tested this with cgroupsPath with test1/test2/test3 as a cgroupsPath, and the behavior is as expected. I have test1/test2/test3 cgroup created before starting runc.
When I do runc start it appropriately joins and modifies test3 cgroup.
Do you have other comments on my approach?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mrunalp @crosbymichael Any feedback on this? This will allow me to launch containers inside userns containers.

c := &configs.Cgroup{
Name: name,
Parent: myCgroupPath,
Expand Down