From 24142a8514d503c42034d50af2798566be552788 Mon Sep 17 00:00:00 2001 From: Mrunal Patel Date: Mon, 21 Mar 2016 12:53:15 -0700 Subject: [PATCH 1/3] Add a flag to enable systemd cgroups support in runc Signed-off-by: Mrunal Patel --- main.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main.go b/main.go index c4cb0b60b..4c25ba82a 100644 --- a/main.go +++ b/main.go @@ -79,6 +79,10 @@ func main() { Value: "criu", Usage: "path to the criu binary used for checkpoint and restore", }, + cli.BoolFlag{ + Name: "systemd-cgroup", + Usage: "enable systemd cgroup support, expects cgroupsPath to be of form \"slice:prefix:name\" for e.g. \"system.slice:runc:434234\"", + }, } app.Commands = []cli.Command{ checkpointCommand, From 7e91a966056e5013e479619a9008a08a0425a1c1 Mon Sep 17 00:00:00 2001 From: Mrunal Patel Date: Mon, 21 Mar 2016 12:53:46 -0700 Subject: [PATCH 2/3] Add support for systemd cgroups in runc Signed-off-by: Mrunal Patel --- restore.go | 2 +- spec.go | 49 +++++++++++++++++++++++++++++++++++-------------- spec_test.go | 4 ++-- utils.go | 13 +++++++++++-- 4 files changed, 49 insertions(+), 19 deletions(-) diff --git a/restore.go b/restore.go index 873540d2e..9d071a939 100644 --- a/restore.go +++ b/restore.go @@ -92,7 +92,7 @@ using the runc checkpoint command.`, if err != nil { fatal(err) } - config, err := createLibcontainerConfig(id, spec) + config, err := createLibcontainerConfig(id, context.GlobalBool("systemd-cgroup"), spec) if err != nil { fatal(err) } diff --git a/spec.go b/spec.go index 87bbff886..bee95dc85 100644 --- a/spec.go +++ b/spec.go @@ -215,7 +215,7 @@ func loadSpec(cPath string) (spec *specs.Spec, err error) { return spec, validateProcessSpec(&spec.Process) } -func createLibcontainerConfig(cgroupName string, spec *specs.Spec) (*configs.Config, error) { +func createLibcontainerConfig(cgroupName string, useSystemdCgroup bool, spec *specs.Spec) (*configs.Config, error) { // runc's cwd will always be the bundle path rcwd, err := os.Getwd() if err != nil { @@ -266,7 +266,7 @@ func createLibcontainerConfig(cgroupName string, spec *specs.Spec) (*configs.Con if err := setupUserNamespace(spec, config); err != nil { return nil, err } - c, err := createCgroupConfig(cgroupName, spec) + c, err := createCgroupConfig(cgroupName, useSystemdCgroup, spec) if err != nil { return nil, err } @@ -311,26 +311,47 @@ func createLibcontainerMount(cwd string, m specs.Mount) *configs.Mount { } } -func createCgroupConfig(name string, spec *specs.Spec) (*configs.Cgroup, error) { +func createCgroupConfig(name string, useSystemdCgroup bool, spec *specs.Spec) (*configs.Cgroup, error) { var ( err error myCgroupPath string ) - if spec.Linux.CgroupsPath != nil { - myCgroupPath = libcontainerUtils.CleanPath(*spec.Linux.CgroupsPath) - } else { - myCgroupPath, err = cgroups.GetThisCgroupDir("devices") - if err != nil { - return nil, err - } - myCgroupPath = filepath.Join(myCgroupPath, name) - } - c := &configs.Cgroup{ - Path: myCgroupPath, Resources: &configs.Resources{}, } + + if spec.Linux.CgroupsPath != nil { + myCgroupPath = libcontainerUtils.CleanPath(*spec.Linux.CgroupsPath) + } + + if useSystemdCgroup { + if myCgroupPath == "" { + c.Parent = "system.slice" + c.ScopePrefix = "runc" + c.Name = name + } else { + // Parse the path from expected "slice:prefix:name" + // for e.g. "system.slice:docker:1234" + parts := strings.Split(myCgroupPath, ":") + if len(parts) != 3 { + return nil, fmt.Errorf("expected cgroupsPath to be of format \"slice:prefix:name\" for systemd cgroups") + } + c.Parent = parts[0] + c.ScopePrefix = parts[1] + c.Name = parts[2] + } + } else { + if myCgroupPath == "" { + myCgroupPath, err = cgroups.GetThisCgroupDir("devices") + if err != nil { + return nil, err + } + myCgroupPath = filepath.Join(myCgroupPath, name) + } + c.Path = myCgroupPath + } + c.Resources.AllowedDevices = allowedDevices r := spec.Linux.Resources if r == nil { diff --git a/spec_test.go b/spec_test.go index 156ee62cd..73af04c37 100644 --- a/spec_test.go +++ b/spec_test.go @@ -15,7 +15,7 @@ func TestLinuxCgroupsPathSpecified(t *testing.T) { spec := &specs.Spec{} spec.Linux.CgroupsPath = &cgroupsPath - cgroup, err := createCgroupConfig("ContainerID", spec) + cgroup, err := createCgroupConfig("ContainerID", false, spec) if err != nil { t.Errorf("Couldn't create Cgroup config: %v", err) } @@ -28,7 +28,7 @@ func TestLinuxCgroupsPathSpecified(t *testing.T) { func TestLinuxCgroupsPathNotSpecified(t *testing.T) { spec := &specs.Spec{} - cgroup, err := createCgroupConfig("ContainerID", spec) + cgroup, err := createCgroupConfig("ContainerID", false, spec) if err != nil { t.Errorf("Couldn't create Cgroup config: %v", err) } diff --git a/utils.go b/utils.go index 01b07e0a0..f5d29c3eb 100644 --- a/utils.go +++ b/utils.go @@ -12,6 +12,7 @@ import ( "github.com/Sirupsen/logrus" "github.com/codegangsta/cli" "github.com/opencontainers/runc/libcontainer" + "github.com/opencontainers/runc/libcontainer/cgroups/systemd" "github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/specs/specs-go" ) @@ -146,7 +147,15 @@ func loadFactory(context *cli.Context) (libcontainer.Factory, error) { if err != nil { return nil, err } - return libcontainer.New(abs, libcontainer.Cgroupfs, func(l *libcontainer.LinuxFactory) error { + cgroupManager := libcontainer.Cgroupfs + if context.GlobalBool("systemd-cgroup") { + if systemd.UseSystemd() { + cgroupManager = libcontainer.SystemdCgroups + } else { + return nil, fmt.Errorf("systemd cgroup flag passed, but systemd support for managing cgroups is not available.") + } + } + return libcontainer.New(abs, cgroupManager, func(l *libcontainer.LinuxFactory) error { l.CriuPath = context.GlobalString("criu") return nil }) @@ -285,7 +294,7 @@ func createPidFile(path string, process *libcontainer.Process) error { } func createContainer(context *cli.Context, id string, spec *specs.Spec) (libcontainer.Container, error) { - config, err := createLibcontainerConfig(id, spec) + config, err := createLibcontainerConfig(id, context.GlobalBool("systemd-cgroup"), spec) if err != nil { return nil, err } From 0e4170849f17520c42f114baa8c1353803bb78e9 Mon Sep 17 00:00:00 2001 From: Mrunal Patel Date: Tue, 22 Mar 2016 17:09:51 -0700 Subject: [PATCH 3/3] Update man page for runc Signed-off-by: Mrunal Patel --- man/runc.8.md | 1 + 1 file changed, 1 insertion(+) diff --git a/man/runc.8.md b/man/runc.8.md index ccfc5332c..0ebedfad9 100644 --- a/man/runc.8.md +++ b/man/runc.8.md @@ -48,5 +48,6 @@ value for "bundle" is the current directory. --log-format "text" set the format used by logs ('text' (default), or 'json') --root "/run/opencontainer/containers" root directory for storage of container state (this should be located in tmpfs) --criu "criu" path to the criu binary used for checkpoint and restore + --systemd-cgroup enable systemd cgroup support, expects cgroupsPath to be of form "slice:prefix:name" for e.g. "system.slice:runc:434234" --help, -h show help --version, -v print the version