Skip to content
This repository was archived by the owner on May 12, 2021. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
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
37 changes: 35 additions & 2 deletions cli/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,13 @@ func createCgroupsFiles(containerID string, cgroupsDirPath string, cgroupsPathLi
}

if strings.Contains(cgroupsPath, "cpu") && cgroupsDirPath != "" {
parent := strings.TrimSuffix(cgroupsPath, cgroupsDirPath)
copyParentCPUSet(cgroupsPath, parent)
root, err := getCgroupsRootPath(procMountInfo)
if err != nil {
return err
}
if err := repeatCopy(cgroupsPath, root); err != nil {
return fmt.Errorf("Fail to copy cpuset from parent: %s", err)
}
}

tasksFilePath := filepath.Join(cgroupsPath, cgroupsTasksFile)
Expand Down Expand Up @@ -348,6 +353,34 @@ func createPIDFile(pidFilePath string, pid int) error {
return nil
}

// repeatCopy copies data from parent directory until
// cpuset cgroup root to avoid parent has zero data.
func repeatCopy(path, root string) error {
if !fileExists(filepath.Join(path, "cpuset.cpus")) || !fileExists(filepath.Join(path, "cpuset.mems")) {
return nil
}

parent := filepath.Dir(path)
if filepath.Clean(parent) == root {
return nil
}

// cgroup path get error, stop the loop
if parent == path {
return fmt.Errorf("cpu cgroup gets wrong path %s", path)
}

if err := repeatCopy(parent, root); err != nil {
return err
}

if err := os.MkdirAll(path, cgroupsDirMode); err != nil {
return err
}

return copyParentCPUSet(path, parent)
}

// copyParentCPUSet copies the cpuset.cpus and cpuset.mems from the parent
// directory to the current directory if the file's contents are 0
func copyParentCPUSet(current, parent string) error {
Expand Down
6 changes: 3 additions & 3 deletions cli/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -631,14 +631,14 @@ func TestCreateCreateCgroupsFilesFail(t *testing.T) {
}

// Override
cgroupsDirPath = filepath.Join(tmpdir, "cgroups")
err = os.MkdirAll(cgroupsDirPath, testDirMode)
cgroupsRootPath = filepath.Join(tmpdir, "cgroups")
err = os.MkdirAll(cgroupsRootPath, testDirMode)
assert.NoError(err)

// Set a relative path
spec.Linux.CgroupsPath = "./a/relative/path"

dir := filepath.Join(cgroupsDirPath, "memory")
dir := filepath.Join(cgroupsRootPath, "memory")

// Stop directory from being created
err = os.MkdirAll(dir, os.FileMode(0000))
Expand Down
16 changes: 8 additions & 8 deletions cli/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const (

var errNeedLinuxResource = errors.New("Linux resource cannot be empty")

var cgroupsDirPath string
var cgroupsRootPath string

var procMountInfo = "/proc/self/mountinfo"

Expand Down Expand Up @@ -189,14 +189,14 @@ func processCgroupsPathForResource(ociSpec oci.CompatOCISpec, resource string, i
}

var err error
cgroupsDirPath, err = getCgroupsDirPath(procMountInfo)
cgroupsRootPath, err = getCgroupsRootPath(procMountInfo)
if err != nil {
return "", fmt.Errorf("get CgroupsDirPath error: %s", err)
return "", fmt.Errorf("get CgroupsRootPath error: %s", err)
}

// Relative cgroups path provided.
if filepath.IsAbs(ociSpec.Linux.CgroupsPath) == false {
return filepath.Join(cgroupsDirPath, resource, ociSpec.Linux.CgroupsPath), nil
return filepath.Join(cgroupsRootPath, resource, ociSpec.Linux.CgroupsPath), nil
}

// Absolute cgroups path provided.
Expand All @@ -214,7 +214,7 @@ func processCgroupsPathForResource(ociSpec oci.CompatOCISpec, resource string, i
// According to the OCI spec, an absolute path should be
// interpreted as relative to the system cgroup mount point
// when there is no cgroup mount point.
return filepath.Join(cgroupsDirPath, resource, ociSpec.Linux.CgroupsPath), nil
return filepath.Join(cgroupsRootPath, resource, ociSpec.Linux.CgroupsPath), nil
}

if cgroupMount.Destination == "" {
Expand Down Expand Up @@ -306,9 +306,9 @@ func noNeedForOutput(detach bool, tty bool) bool {
return true
}

func getCgroupsDirPath(mountInfoFile string) (string, error) {
if cgroupsDirPath != "" {
return cgroupsDirPath, nil
func getCgroupsRootPath(mountInfoFile string) (string, error) {
if cgroupsRootPath != "" {
return cgroupsRootPath, nil
}

f, err := os.Open(mountInfoFile)
Expand Down
20 changes: 10 additions & 10 deletions cli/oci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ func TestProcessCgroupsPathEmptyResources(t *testing.T) {

func TestProcessCgroupsPathRelativePathSuccessful(t *testing.T) {
relativeCgroupsPath := "relative/cgroups/path"
cgroupsDirPath = "/foo/runtime/base"
cgroupsRootPath = "/foo/runtime/base"

ociSpec := oci.CompatOCISpec{}

Expand All @@ -224,15 +224,15 @@ func TestProcessCgroupsPathRelativePathSuccessful(t *testing.T) {
for _, d := range cgroupTestData {
ociSpec.Linux.Resources = d.linuxSpec

p := filepath.Join(cgroupsDirPath, d.resource, relativeCgroupsPath)
p := filepath.Join(cgroupsRootPath, d.resource, relativeCgroupsPath)

testProcessCgroupsPath(t, ociSpec, []string{p})
}
}

func TestProcessCgroupsPathAbsoluteNoCgroupMountSuccessful(t *testing.T) {
absoluteCgroupsPath := "/absolute/cgroups/path"
cgroupsDirPath = "/foo/runtime/base"
cgroupsRootPath = "/foo/runtime/base"

ociSpec := oci.CompatOCISpec{}

Expand All @@ -243,7 +243,7 @@ func TestProcessCgroupsPathAbsoluteNoCgroupMountSuccessful(t *testing.T) {
for _, d := range cgroupTestData {
ociSpec.Linux.Resources = d.linuxSpec

p := filepath.Join(cgroupsDirPath, d.resource, absoluteCgroupsPath)
p := filepath.Join(cgroupsRootPath, d.resource, absoluteCgroupsPath)

testProcessCgroupsPath(t, ociSpec, []string{p})
}
Expand Down Expand Up @@ -422,12 +422,12 @@ func TestIsCgroupMounted(t *testing.T) {

assert.False(isCgroupMounted(os.TempDir()), "%s is not a cgroup", os.TempDir())

cgroupsDirPath = ""
cgroupRootPath, err := getCgroupsDirPath(procMountInfo)
cgroupsRootPath = ""
path, err := getCgroupsRootPath(procMountInfo)
if err != nil {
assert.NoError(err)
}
memoryCgroupPath := filepath.Join(cgroupRootPath, "memory")
memoryCgroupPath := filepath.Join(path, "memory")
if _, err := os.Stat(memoryCgroupPath); os.IsNotExist(err) {
t.Skipf("memory cgroup does not exist: %s", memoryCgroupPath)
}
Expand Down Expand Up @@ -494,15 +494,15 @@ func TestGetCgroupsDirPath(t *testing.T) {
file := filepath.Join(dir, "mountinfo")

//file does not exist, should error here
_, err = getCgroupsDirPath(file)
_, err = getCgroupsRootPath(file)
assert.Error(err)

for _, d := range data {
err := ioutil.WriteFile(file, []byte(d.contents), testFileMode)
assert.NoError(err)

cgroupsDirPath = ""
path, err := getCgroupsDirPath(file)
cgroupsRootPath = ""
path, err := getCgroupsRootPath(file)
if d.expectError {
assert.Error(err, fmt.Sprintf("got %q, test data: %+v", path, d))
} else {
Expand Down