From 15ca5f26878e397056d31e84b4f0937ab173645b Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Thu, 15 Mar 2018 22:42:04 -0400 Subject: Add validation for CGroup parents. Pass CGroups path into runc Signed-off-by: Matthew Heon Closes: #507 Approved by: baude --- libpod/container.go | 11 ++++++++--- libpod/container_internal.go | 8 +++++++- libpod/runtime_ctr.go | 19 +++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/libpod/container.go b/libpod/container.go index d9dd9ad12..40e670300 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -39,8 +39,12 @@ const ( ContainerStatePaused ContainerStatus = iota ) -// DefaultCgroupParent is the default prefix to a cgroup path in libpod -var DefaultCgroupParent = "/libpod_parent" +// CgroupfsDefaultCgroupParent is the cgroup parent for CGroupFS in libpod +const CgroupfsDefaultCgroupParent = "/libpod_parent" + +// SystemdDefaultCgroupParent is the cgroup parent for the systemd cgroup +// manager in libpod +const SystemdDefaultCgroupParent = "system.slice" // LinuxNS represents a Linux namespace type LinuxNS int @@ -851,7 +855,8 @@ func (c *Container) NamespacePath(ns LinuxNS) (string, error) { // CGroupPath returns a cgroups "path" for a given container. func (c *Container) CGroupPath() cgroups.Path { - return cgroups.StaticPath(filepath.Join(c.config.CgroupParent, fmt.Sprintf("libpod-conmon-%s/%s", c.ID(), c.ID()))) + // TODO add support for systemd cgroup paths + return cgroups.StaticPath(filepath.Join(c.config.CgroupParent, fmt.Sprintf("libpod-conmon-%s", c.ID()))) } // RootFsSize returns the root FS size of the container diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 5417c8a4f..644598322 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -160,7 +160,6 @@ func newContainer(rspec *spec.Spec, lockDir string) (*Container, error) { ctr.config.CreatedTime = time.Now() ctr.config.ShmSize = DefaultShmSize - ctr.config.CgroupParent = DefaultCgroupParent ctr.state.BindMounts = make(map[string]string) @@ -1129,6 +1128,13 @@ 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()) + } + logrus.Debugf("Setting CGroup path for container %s to %s", c.ID(), cgroupPath) + g.SetLinuxCgroupsPath(cgroupPath) + return g.Spec(), nil } diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index 4708e0c8f..f5d8e5704 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -3,6 +3,7 @@ package libpod import ( "context" "os" + "path" "path/filepath" "strings" "time" @@ -60,6 +61,24 @@ func (r *Runtime) NewContainer(ctx context.Context, rSpec *spec.Spec, options .. ctr.config.Name = name } + // Check CGroup parent sanity, and set it if it was not set + switch r.config.CgroupManager { + case CgroupfsCgroupsManager: + if ctr.config.CgroupParent == "" { + ctr.config.CgroupParent = CgroupfsDefaultCgroupParent + } else if strings.HasSuffix(path.Base(ctr.config.CgroupParent), ".slice") { + return nil, errors.Wrapf(ErrInvalidArg, "systemd slice received as cgroup parent when using cgroupfs") + } + case SystemdCgroupsManager: + if ctr.config.CgroupParent == "" { + ctr.config.CgroupParent = SystemdDefaultCgroupParent + } else if len(ctr.config.CgroupParent) < 6 || !strings.HasSuffix(path.Base(ctr.config.CgroupParent), ".slice") { + return nil, errors.Wrapf(ErrInvalidArg, "did not receive systemd slice as cgroup parent when using systemd to manage cgroups") + } + default: + return nil, errors.Wrapf(ErrInvalidArg, "unsupported CGroup manager: %s - cannot validate cgroup parent", r.config.CgroupManager) + } + // Set up storage for the container if err := ctr.setupStorage(ctx); err != nil { return nil, err -- cgit v1.2.3-54-g00ecf