From bb9396d6fc6b427a4b44a6fed48bf2046bc211b3 Mon Sep 17 00:00:00 2001 From: Kenfe-Mickael Laventure Date: Wed, 20 Jan 2016 18:04:59 -0800 Subject: [PATCH] Replace Cgroup Parent and Name fields by CgroupsPath Fixes #396 Signed-off-by: Kenfe-Mickael Laventure --- libcontainer/cgroups/fs/apply_raw.go | 23 ++++++++----------- libcontainer/cgroups/systemd/apply_systemd.go | 23 +++++++++++-------- libcontainer/configs/cgroup_unix.go | 10 ++++---- libcontainer/integration/exec_test.go | 11 ++++++--- libcontainer/integration/template_test.go | 3 +-- libcontainer/integration/utils_test.go | 4 ++-- spec.go | 22 +++++++++++++----- 7 files changed, 54 insertions(+), 42 deletions(-) diff --git a/libcontainer/cgroups/fs/apply_raw.go b/libcontainer/cgroups/fs/apply_raw.go index 689023a0ff1..e7e47114edc 100644 --- a/libcontainer/cgroups/fs/apply_raw.go +++ b/libcontainer/cgroups/fs/apply_raw.go @@ -95,11 +95,10 @@ func getCgroupRoot() (string, error) { } type cgroupData struct { - root string - parent string - name string - config *configs.Cgroup - pid int + root string + cgroupspath string + config *configs.Cgroup + pid int } func (m *Manager) Apply(pid int) (err error) { @@ -280,15 +279,11 @@ func getCgroupData(c *configs.Cgroup, pid int) (*cgroupData, error) { return nil, err } - // Clean the parent slice path. - c.Parent = libcontainerUtils.PathClean(c.Parent) - return &cgroupData{ - root: root, - parent: c.Parent, - name: c.Name, - config: c, - pid: pid, + root: root, + cgroupspath: libcontainerUtils.PathClean(c.CgroupsPath), + config: c, + pid: pid, }, nil } @@ -316,7 +311,7 @@ func (raw *cgroupData) path(subsystem string) (string, error) { return "", err } - cgPath := filepath.Join(raw.parent, raw.name) + cgPath := raw.cgroupspath // If the cgroup name/path is absolute do not look relative to the cgroup of the init process. if filepath.IsAbs(cgPath) { // Sometimes subsystems can be mounted togethger as 'cpu,cpuacct'. diff --git a/libcontainer/cgroups/systemd/apply_systemd.go b/libcontainer/cgroups/systemd/apply_systemd.go index 0e3997739ee..b033a3563ab 100644 --- a/libcontainer/cgroups/systemd/apply_systemd.go +++ b/libcontainer/cgroups/systemd/apply_systemd.go @@ -19,6 +19,7 @@ import ( "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups/fs" "github.com/opencontainers/runc/libcontainer/configs" + libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils" ) type Manager struct { @@ -162,10 +163,11 @@ func getIfaceForUnit(unitName string) string { func (m *Manager) Apply(pid int) error { var ( - c = m.Cgroups - unitName = getUnitName(c) - slice = "system.slice" - properties []systemdDbus.Property + c = m.Cgroups + unitName = getUnitName(c) + parent, name = filepath.Split(c.CgroupsPath) + slice = "system.slice" + properties []systemdDbus.Property ) if c.Paths != nil { @@ -185,13 +187,13 @@ func (m *Manager) Apply(pid int) error { return cgroups.EnterPid(m.Paths, pid) } - if c.Parent != "" { - slice = c.Parent + if parent != "" { + slice = libcontainerUtils.PathClean(parent) } properties = append(properties, systemdDbus.PropSlice(slice), - systemdDbus.PropDescription("docker container "+c.Name), + systemdDbus.PropDescription("docker container "+name), newProp("PIDs", []uint32{uint32(pid)}), ) @@ -399,8 +401,8 @@ func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) { } slice := "system.slice" - if c.Parent != "" { - slice = c.Parent + if dir, _ := filepath.Split(c.CgroupsPath); dir != "" { + slice = libcontainerUtils.PathClean(dir) } return filepath.Join(mountpoint, initPath, slice, getUnitName(c)), nil @@ -486,7 +488,8 @@ func (m *Manager) Set(container *configs.Config) error { } func getUnitName(c *configs.Cgroup) string { - return fmt.Sprintf("%s-%s.scope", c.ScopePrefix, c.Name) + _, name := filepath.Split(c.CgroupsPath) + return fmt.Sprintf("%s-%s.scope", c.ScopePrefix, name) } // Atm we can't use the systemd device support because of two missing things: diff --git a/libcontainer/configs/cgroup_unix.go b/libcontainer/configs/cgroup_unix.go index 24c523a650b..4b76142fdb4 100644 --- a/libcontainer/configs/cgroup_unix.go +++ b/libcontainer/configs/cgroup_unix.go @@ -11,15 +11,15 @@ const ( ) type Cgroup struct { - Name string `json:"name"` - - // name of parent cgroup or slice - Parent string `json:"parent"` + // CgroupsPath specifies the path to cgroups that are created and/or joined by the container. + // The path is assumed to be relative to the host system cgroup mountpoint. + CgroupsPath string `json:"cgroupsPath"` // ScopePrefix decribes prefix for the scope name ScopePrefix string `json:"scope_prefix"` - // Paths represent the cgroups paths to join + // Paths represent the absolute cgroups paths to join. + // This takes precedence over CgroupsPath. Paths map[string]string // Resources contains various cgroups settings to apply diff --git a/libcontainer/integration/exec_test.go b/libcontainer/integration/exec_test.go index ca8609c814d..00de083feae 100644 --- a/libcontainer/integration/exec_test.go +++ b/libcontainer/integration/exec_test.go @@ -466,6 +466,8 @@ func testFreeze(t *testing.T, systemd bool) { f := factory if systemd { f = systemdFactory + _, name := filepath.Split(config.Cgroups.CgroupsPath) + config.Cgroups.CgroupsPath = filepath.Join("system.slice", name) } container, err := f.Create("test", config) @@ -521,7 +523,8 @@ func testCpuShares(t *testing.T, systemd bool) { config := newTemplateConfig(rootfs) if systemd { - config.Cgroups.Parent = "system.slice" + _, name := filepath.Split(config.Cgroups.CgroupsPath) + config.Cgroups.CgroupsPath = filepath.Join("system.slice", name) } config.Cgroups.Resources.CpuShares = 1 @@ -553,7 +556,8 @@ func testPids(t *testing.T, systemd bool) { config := newTemplateConfig(rootfs) if systemd { - config.Cgroups.Parent = "system.slice" + _, name := filepath.Split(config.Cgroups.CgroupsPath) + config.Cgroups.CgroupsPath = filepath.Join("system.slice", name) } config.Cgroups.Resources.PidsLimit = -1 @@ -621,7 +625,8 @@ func testRunWithKernelMemory(t *testing.T, systemd bool) { config := newTemplateConfig(rootfs) if systemd { - config.Cgroups.Parent = "system.slice" + _, name := filepath.Split(config.Cgroups.CgroupsPath) + config.Cgroups.CgroupsPath = filepath.Join("system.slice", name) } config.Cgroups.Resources.KernelMemory = 52428800 diff --git a/libcontainer/integration/template_test.go b/libcontainer/integration/template_test.go index 75f5861ae37..f4c5b03de9b 100644 --- a/libcontainer/integration/template_test.go +++ b/libcontainer/integration/template_test.go @@ -46,8 +46,7 @@ func newTemplateConfig(rootfs string) *configs.Config { {Type: configs.NEWNET}, }), Cgroups: &configs.Cgroup{ - Name: "test", - Parent: "integration", + CgroupsPath: "integration/test", Resources: &configs.Resources{ MemorySwappiness: -1, AllowAllDevices: false, diff --git a/libcontainer/integration/utils_test.go b/libcontainer/integration/utils_test.go index 3dcd0bb1687..785f3322d75 100644 --- a/libcontainer/integration/utils_test.go +++ b/libcontainer/integration/utils_test.go @@ -93,8 +93,8 @@ func copyBusybox(dest string) error { func newContainer(config *configs.Config) (libcontainer.Container, error) { f := factory - - if config.Cgroups != nil && config.Cgroups.Parent == "system.slice" { + dir, _ := filepath.Split(config.Cgroups.CgroupsPath) + if config.Cgroups != nil && dir == "system.slice" { f = systemdFactory } diff --git a/spec.go b/spec.go index 5564dd3040b..9acd3f4f4e3 100644 --- a/spec.go +++ b/spec.go @@ -18,6 +18,7 @@ import ( "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/seccomp" + libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils" "github.com/opencontainers/specs" ) @@ -449,14 +450,23 @@ func createLibcontainerMount(cwd, dest string, m specs.Mount) *configs.Mount { } func createCgroupConfig(name string, spec *specs.LinuxRuntimeSpec, devices []*configs.Device) (*configs.Cgroup, error) { - myCgroupPath, err := cgroups.GetThisCgroupDir("devices") - if err != nil { - return nil, err + var ( + err error + myCgroupPath string + ) + + if spec.Linux.CgroupsPath != "" { + myCgroupPath = libcontainerUtils.PathClean(spec.Linux.CgroupsPath) + } else { + myCgroupPath, err = cgroups.GetThisCgroupDir("devices") + if err != nil { + return nil, err + } } + c := &configs.Cgroup{ - Name: name, - Parent: myCgroupPath, - Resources: &configs.Resources{}, + CgroupsPath: filepath.Join(myCgroupPath, name), + Resources: &configs.Resources{}, } c.Resources.AllowedDevices = append(devices, allowedDevices...) r := spec.Linux.Resources