From 8b32914065c4a32eaf5cb1c759a89ea514a3999b Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Mon, 25 Jan 2016 22:34:48 +1100 Subject: [PATCH] cgroup: systemd: properly expand systemd slice names Rather than using '/' to denote hierarchy in slice names, systemd uses '-' in an odd way. This results in runC incorrectly assuming that certain kernel features are missing (and using inconsistent paths for the cgroups not supported by systemd), because the "subsystem path" used is not the one that systemd has created. Fix all of this by properly expanding slice names. Signed-off-by: Aleksa Sarai --- libcontainer/cgroups/systemd/apply_systemd.go | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/libcontainer/cgroups/systemd/apply_systemd.go b/libcontainer/cgroups/systemd/apply_systemd.go index 5b070dd0545..db020a971fe 100644 --- a/libcontainer/cgroups/systemd/apply_systemd.go +++ b/libcontainer/cgroups/systemd/apply_systemd.go @@ -387,6 +387,28 @@ func joinPids(c *configs.Cgroup, pid int) error { return nil } +// systemd represents slice heirarchy using `-`, so we need to follow suit when +// generating the path of slice. Essentially, test-a-b.slice becomes +// test.slice/test-a.slice/test-a-b.slice. +func expandSlice(slice string) (string, error) { + suffix := ".slice" + sliceName := strings.TrimSuffix(slice, suffix) + + var path, prefix string + for _, component := range strings.Split(sliceName, "-") { + // test--a.slice isn't permitted, nor is -test.slice. + if component == "" { + return "", fmt.Errorf("invalid slice name: %s", slice) + } + + // Append the component to the path and to the prefix. + path += prefix + component + suffix + "/" + prefix += component + "-" + } + + return path, nil +} + func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) { mountpoint, err := cgroups.FindCgroupMountpoint(subsystem) if err != nil { @@ -403,6 +425,11 @@ func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) { slice = c.Parent } + slice, err = expandSlice(slice) + if err != nil { + return "", err + } + return filepath.Join(mountpoint, initPath, slice, getUnitName(c)), nil }