Skip to content

Commit 4dce383

Browse files
Merge pull request #1372 from cloudfoundry-incubator/cpuset-mount-root
Handle container creation when cgroups have already been mounted in another location
2 parents 388bdc9 + 0e9abc8 commit 4dce383

File tree

3 files changed

+48
-1
lines changed

3 files changed

+48
-1
lines changed

libcontainer/cgroups/fs/cpuset.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,11 @@ func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) erro
5757
if dir == "" {
5858
return nil
5959
}
60-
root, err := getCgroupRoot()
60+
mountInfo, err := ioutil.ReadFile("/proc/self/mountinfo")
6161
if err != nil {
6262
return err
6363
}
64+
root := filepath.Dir(cgroups.GetClosestMountpointAncestor(dir, string(mountInfo)))
6465
// 'ensureParent' start with parent because we don't want to
6566
// explicitly inherit from parent, it could conflict with
6667
// 'cpuset.cpu_exclusive'.

libcontainer/cgroups/utils.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,21 @@ func isSubsystemAvailable(subsystem string) bool {
6666
return avail
6767
}
6868

69+
func GetClosestMountpointAncestor(dir, mountinfo string) string {
70+
deepestMountPoint := ""
71+
for _, mountInfoEntry := range strings.Split(mountinfo, "\n") {
72+
mountInfoParts := strings.Fields(mountInfoEntry)
73+
if len(mountInfoParts) < 5 {
74+
continue
75+
}
76+
mountPoint := mountInfoParts[4]
77+
if strings.HasPrefix(mountPoint, deepestMountPoint) && strings.HasPrefix(dir, mountPoint) {
78+
deepestMountPoint = mountPoint
79+
}
80+
}
81+
return deepestMountPoint
82+
}
83+
6984
func FindCgroupMountpointDir() (string, error) {
7085
f, err := os.Open("/proc/self/mountinfo")
7186
if err != nil {

libcontainer/cgroups/utils_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,3 +300,34 @@ func TestIgnoreCgroup2Mount(t *testing.T) {
300300
}
301301
}
302302
}
303+
304+
const fakeMountInfo = ` 18 24 0:17 / /sys rw,nosuid,nodev,noexec,relatime - sysfs sysfs rw
305+
100 99 1:31 / /foo/bar rw,relatime - fake fake rw,fake
306+
100 99 1:31 / /foo/bar/baz2 rw,relatime - fake fake rw,fake
307+
100 99 1:31 / /foo/bar/baz rw,relatime - fake fake rw,fake
308+
100 99 1:31 / /foo/bar/bazza rw,relatime - fake fake rw,fake
309+
100 99 1:31 / /foo/bar/baz3 rw,relatime - fake fake rw,fake
310+
100 99 1:31 / /foo rw,relatime - fake fake rw,fake
311+
100 99 1:31 / /unrelated rw,relatime - fake fake rw,fake
312+
100 99 1:31 / / rw,relatime - fake fake rw,fake
313+
`
314+
315+
func TestGetClosestMountpointAncestor(t *testing.T) {
316+
testCases := []struct {
317+
input string
318+
mountinfos string
319+
output string
320+
}{
321+
{input: "/foo/bar/baz/a/b/c", mountinfos: fakeMountInfo, output: "/foo/bar/baz"},
322+
{input: "/foo/bar/baz", mountinfos: fakeMountInfo, output: "/foo/bar/baz"},
323+
{input: "/foo/bar/bazza", mountinfos: fakeMountInfo, output: "/foo/bar/bazza"},
324+
{input: "/a/b/c/d", mountinfos: fakeMountInfo, output: "/"},
325+
}
326+
327+
for _, c := range testCases {
328+
mountpoint := GetClosestMountpointAncestor(c.input, c.mountinfos)
329+
if mountpoint != c.output {
330+
t.Errorf("expected %s, got %s", c.output, mountpoint)
331+
}
332+
}
333+
}

0 commit comments

Comments
 (0)