Merge pull request #667 from mrunalp/systemd_cgroups

Add support for enabling systemd cgroups
This commit is contained in:
Michael Crosby 2016-03-23 16:14:03 -07:00
commit 24950964ec
6 changed files with 54 additions and 19 deletions

View File

@ -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,

View File

@ -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

View File

@ -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)
}

49
spec.go
View File

@ -248,7 +248,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 {
@ -299,7 +299,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
}
@ -344,26 +344,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 {

View File

@ -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)
}

View File

@ -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
}