Major fixes to systemd cgroup handling

Signed-off-by: Matthew Heon <matthew.heon@gmail.com>

Closes: #507
Approved by: baude
This commit is contained in:
Matthew Heon
2018-03-21 11:28:16 -04:00
committed by Atomic Bot
parent fee9ec1858
commit df83d361e4
6 changed files with 51 additions and 24 deletions

View File

@@ -6,7 +6,6 @@ import (
"path/filepath"
"time"
"github.com/containerd/cgroups"
"github.com/containernetworking/cni/pkg/types"
cnitypes "github.com/containernetworking/cni/pkg/types/current"
"github.com/containernetworking/plugins/pkg/ns"
@@ -854,9 +853,15 @@ func (c *Container) NamespacePath(ns LinuxNS) (string, error) {
}
// CGroupPath returns a cgroups "path" for a given container.
func (c *Container) CGroupPath() cgroups.Path {
// TODO add support for systemd cgroup paths
return cgroups.StaticPath(filepath.Join(c.config.CgroupParent, fmt.Sprintf("libpod-conmon-%s", c.ID())))
func (c *Container) CGroupPath() (string, error) {
switch c.runtime.config.CgroupManager {
case CgroupfsCgroupsManager:
return filepath.Join(c.config.CgroupParent, fmt.Sprintf("libpod-conmon-%s", c.ID())), nil
case SystemdCgroupsManager:
return filepath.Join(c.config.CgroupParent, createUnitName("libpod", c.ID())), nil
default:
return "", errors.Wrapf(ErrInvalidArg, "unsupported CGroup manager %s in use", c.runtime.config.CgroupManager)
}
}
// RootFsSize returns the root FS size of the container

View File

@@ -7,6 +7,7 @@ import (
"io"
"io/ioutil"
"os"
"path"
"path/filepath"
"regexp"
"strings"
@@ -1128,12 +1129,19 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
g.AddProcessEnv("container", "libpod")
}
cgroupPath, err := c.CGroupPath()("")
if err != nil {
return nil, errors.Wrapf(err, "error retrieving CGroup path for container %s", c.ID())
if c.runtime.config.CgroupManager == SystemdCgroupsManager {
// When runc is set to use Systemd as a cgroup manager, it
// expects cgroups to be passed as follows:
// slice:prefix:name
g.SetLinuxCgroupsPath(path.Base(c.config.CgroupParent) + ":" + "libpod" + ":" + c.ID())
} else {
cgroupPath, err := c.CGroupPath()
if err != nil {
return nil, err
}
logrus.Debugf("Setting CGroup path for container %s to %s", c.ID(), cgroupPath)
g.SetLinuxCgroupsPath(cgroupPath)
}
logrus.Debugf("Setting CGroup path for container %s to %s", c.ID(), cgroupPath)
g.SetLinuxCgroupsPath(cgroupPath)
return g.Spec(), nil
}

View File

@@ -27,9 +27,9 @@ func (c *Container) GetContainerPids() ([]string, error) {
// Gets the pids for a container without locking. should only be called from a func where
// locking has already been established.
func (c *Container) getContainerPids() ([]string, error) {
cgroupPath, err := c.CGroupPath()("")
cgroupPath, err := c.CGroupPath()
if err != nil {
return nil, errors.Wrapf(err, "error getting cgroup path for container %s", c.ID())
return nil, err
}
taskFile := filepath.Join("/sys/fs/cgroup/pids", cgroupPath, "tasks")

View File

@@ -321,19 +321,26 @@ func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string) (er
// Move conmon to specified cgroup
if r.cgroupManager == SystemdCgroupsManager {
logrus.Infof("Running conmon under slice %s and unitName %s", cgroupParent, createUnitName("libpod-conmon", ctr.ID()))
if err = utils.RunUnderSystemdScope(cmd.Process.Pid, cgroupParent, createUnitName("libpod-conmon", ctr.ID())); err != nil {
unitName := createUnitName("libpod", ctr.ID())
logrus.Infof("Running conmon under slice %s and unitName %s", cgroupParent, unitName)
if err = utils.RunUnderSystemdScope(cmd.Process.Pid, cgroupParent, unitName); err != nil {
logrus.Warnf("Failed to add conmon to systemd sandbox cgroup: %v", err)
}
} else {
control, err := cgroups.New(cgroups.V1, cgroups.StaticPath(filepath.Join(cgroupParent, "/libpod-conmon-"+ctr.ID())), &spec.LinuxResources{})
cgroupPath, err := ctr.CGroupPath()
if err != nil {
logrus.Warnf("Failed to add conmon to cgroupfs sandbox cgroup: %v", err)
logrus.Errorf("Failed to generate CGroup path for conmon: %v", err)
} else {
// we need to remove this defer and delete the cgroup once conmon exits
// maybe need a conmon monitor?
if err := control.Add(cgroups.Process{Pid: cmd.Process.Pid}); err != nil {
control, err := cgroups.New(cgroups.V1, cgroups.StaticPath(cgroupPath), &spec.LinuxResources{})
if err != nil {
logrus.Warnf("Failed to add conmon to cgroupfs sandbox cgroup: %v", err)
} else {
// we need to remove this defer and delete the cgroup once conmon exits
// maybe need a conmon monitor?
if err := control.Add(cgroups.Process{Pid: cmd.Process.Pid}); err != nil {
logrus.Warnf("Failed to add conmon to cgroupfs sandbox cgroup: %v", err)
}
}
}
}

View File

@@ -43,9 +43,14 @@ func (c *Container) GetContainerStats(previousStats *ContainerStats) (*Container
return stats, nil
}
cgroup, err := cgroups.Load(cgroups.V1, c.CGroupPath())
cgroupPath, err := c.CGroupPath()
if err != nil {
return stats, errors.Wrapf(err, "unable to load cgroup at %+v", c.CGroupPath())
return nil, err
}
cgroup, err := cgroups.Load(cgroups.V1, cgroups.StaticPath(cgroupPath))
if err != nil {
return stats, errors.Wrapf(err, "unable to load cgroup at %s", cgroupPath)
}
cgroupStats, err := cgroup.Stat()