mirror of
https://github.com/containers/podman.git
synced 2025-07-04 10:10:32 +08:00
Create pod CGroups when using the systemd cgroup driver
Signed-off-by: Matthew Heon <matthew.heon@gmail.com> Closes: #1266 Approved by: baude
This commit is contained in:
@ -24,8 +24,14 @@ func (r *OCIRuntime) moveConmonToCgroup(ctr *Container, cgroupParent string, cmd
|
||||
if r.cgroupManager == SystemdCgroupsManager {
|
||||
unitName := createUnitName("libpod-conmon", 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 {
|
||||
realCgroupParent := cgroupParent
|
||||
splitParent := strings.Split(cgroupParent, "/")
|
||||
if strings.HasSuffix(cgroupParent, ".slice") && len(splitParent) > 1 {
|
||||
realCgroupParent = splitParent[len(splitParent)-1]
|
||||
}
|
||||
|
||||
logrus.Infof("Running conmon under slice %s and unitName %s", realCgroupParent, unitName)
|
||||
if err := utils.RunUnderSystemdScope(cmd.Process.Pid, realCgroupParent, unitName); err != nil {
|
||||
logrus.Warnf("Failed to add conmon to systemd sandbox cgroup: %v", err)
|
||||
}
|
||||
} else {
|
||||
|
@ -2,6 +2,7 @@ package libpod
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
@ -67,8 +68,11 @@ func (p *Pod) refresh() error {
|
||||
if p.config.UsePodCgroup {
|
||||
switch p.runtime.config.CgroupManager {
|
||||
case SystemdCgroupsManager:
|
||||
// NOOP for now, until proper systemd cgroup management
|
||||
// is implemented
|
||||
cgroupPath, err := systemdSliceFromPath(p.config.CgroupParent, fmt.Sprintf("libpod_pod_%s", p.ID()))
|
||||
if err != nil {
|
||||
logrus.Errorf("Error creating CGroup for pod %s: %v", p.ID(), err)
|
||||
}
|
||||
p.state.CgroupPath = cgroupPath
|
||||
case CgroupfsCgroupsManager:
|
||||
p.state.CgroupPath = filepath.Join(p.config.CgroupParent, p.ID())
|
||||
|
||||
|
@ -4,6 +4,7 @@ package libpod
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@ -70,12 +71,23 @@ func (r *Runtime) NewPod(options ...PodCreateOption) (*Pod, error) {
|
||||
} else if len(pod.config.CgroupParent) < 6 || !strings.HasSuffix(path.Base(pod.config.CgroupParent), ".slice") {
|
||||
return nil, errors.Wrapf(ErrInvalidArg, "did not receive systemd slice as cgroup parent when using systemd to manage cgroups")
|
||||
}
|
||||
// Creating CGroup path is currently a NOOP until proper systemd
|
||||
// cgroup management is merged
|
||||
// If we are set to use pod cgroups, set the cgroup parent that
|
||||
// all containers in the pod will share
|
||||
if pod.config.UsePodCgroup {
|
||||
cgroupPath, err := systemdSliceFromPath(pod.config.CgroupParent, fmt.Sprintf("libpod_pod_%s", pod.ID()))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to create pod cgroup for pod %s", pod.ID())
|
||||
}
|
||||
pod.state.CgroupPath = cgroupPath
|
||||
}
|
||||
default:
|
||||
return nil, errors.Wrapf(ErrInvalidArg, "unsupported CGroup manager: %s - cannot validate cgroup parent", r.config.CgroupManager)
|
||||
}
|
||||
|
||||
if pod.config.UsePodCgroup {
|
||||
logrus.Debugf("Got pod cgroup as %s", pod.state.CgroupPath)
|
||||
}
|
||||
|
||||
if err := r.state.AddPod(pod); err != nil {
|
||||
return nil, errors.Wrapf(err, "error adding pod to state")
|
||||
}
|
||||
@ -91,11 +103,20 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool)
|
||||
return ErrRuntimeStopped
|
||||
}
|
||||
|
||||
if !p.valid {
|
||||
if ok, _ := r.state.HasPod(p.ID()); !ok {
|
||||
// Pod was either already removed, or never existed to
|
||||
// begin with
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
if !p.valid {
|
||||
return ErrPodRemoved
|
||||
// Force a pod update
|
||||
if err := p.updatePod(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctrs, err := r.state.PodContainers(p)
|
||||
@ -216,20 +237,27 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool)
|
||||
|
||||
// Remove pod cgroup, if present
|
||||
if p.state.CgroupPath != "" {
|
||||
switch p.runtime.config.CgroupManager {
|
||||
case SystemdCgroupsManager:
|
||||
// NOOP for now, until proper systemd cgroup management
|
||||
// is implemented
|
||||
case CgroupfsCgroupsManager:
|
||||
// Delete the cgroupfs cgroup
|
||||
logrus.Debugf("Removing pod cgroup %s", p.state.CgroupPath)
|
||||
|
||||
switch p.runtime.config.CgroupManager {
|
||||
case SystemdCgroupsManager:
|
||||
if err := deleteSystemdCgroup(p.state.CgroupPath); err != nil {
|
||||
// The pod is already almost gone.
|
||||
// No point in hard-failing if we fail
|
||||
// this bit of cleanup.
|
||||
logrus.Errorf("Error deleting pod %s cgroup %s: %v", p.ID(), p.state.CgroupPath, err)
|
||||
}
|
||||
case CgroupfsCgroupsManager:
|
||||
// Delete the cgroupfs cgroup
|
||||
cgroup, err := cgroups.Load(cgroups.V1, cgroups.StaticPath(p.state.CgroupPath))
|
||||
if err != nil && err != cgroups.ErrCgroupDeleted {
|
||||
return err
|
||||
} else if err == nil {
|
||||
if err := cgroup.Delete(); err != nil {
|
||||
return err
|
||||
// The pod is already almost gone.
|
||||
// No point in hard-failing if we fail
|
||||
// this bit of cleanup.
|
||||
logrus.Errorf("Error deleting pod %s cgroup %s: %v", p.ID(), p.state.CgroupPath, err)
|
||||
}
|
||||
}
|
||||
default:
|
||||
|
@ -9,10 +9,12 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
"github.com/containers/image/signature"
|
||||
"github.com/containers/image/types"
|
||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Runtime API constants
|
||||
@ -123,6 +125,62 @@ func WaitForFile(path string, timeout time.Duration) error {
|
||||
}
|
||||
}
|
||||
|
||||
// systemdSliceFromPath makes a new systemd slice under the given parent with
|
||||
// the given name.
|
||||
// The parent must be a slice. The name must NOT include ".slice"
|
||||
func systemdSliceFromPath(parent, name string) (string, error) {
|
||||
cgroupPath, err := assembleSystemdCgroupName(parent, name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
logrus.Debugf("Created cgroup path %s for parent %s and name %s", cgroupPath, parent, name)
|
||||
|
||||
if err := makeSystemdCgroup(cgroupPath); err != nil {
|
||||
return "", errors.Wrapf(err, "error creating cgroup %s", cgroupPath)
|
||||
}
|
||||
|
||||
logrus.Debugf("Created cgroup %s", cgroupPath)
|
||||
|
||||
return cgroupPath, nil
|
||||
}
|
||||
|
||||
// makeSystemdCgroup creates a systemd CGroup at the given location.
|
||||
func makeSystemdCgroup(path string) error {
|
||||
controller, err := cgroups.NewSystemd(SystemdDefaultCgroupParent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return controller.Create(path, &spec.LinuxResources{})
|
||||
}
|
||||
|
||||
// deleteSystemdCgroup deletes the systemd cgroup at the given location
|
||||
func deleteSystemdCgroup(path string) error {
|
||||
controller, err := cgroups.NewSystemd(SystemdDefaultCgroupParent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return controller.Delete(path)
|
||||
}
|
||||
|
||||
// assembleSystemdCgroupName creates a systemd cgroup path given a base and
|
||||
// a new component to add.
|
||||
// The base MUST be systemd slice (end in .slice)
|
||||
func assembleSystemdCgroupName(baseSlice, newSlice string) (string, error) {
|
||||
const sliceSuffix = ".slice"
|
||||
|
||||
if !strings.HasSuffix(baseSlice, sliceSuffix) {
|
||||
return "", errors.Wrapf(ErrInvalidArg, "cannot assemble cgroup path with base %q - must end in .slice", baseSlice)
|
||||
}
|
||||
|
||||
noSlice := strings.TrimSuffix(baseSlice, sliceSuffix)
|
||||
final := fmt.Sprintf("%s/%s-%s%s", baseSlice, noSlice, newSlice, sliceSuffix)
|
||||
|
||||
return final, nil
|
||||
}
|
||||
|
||||
type byDestination []spec.Mount
|
||||
|
||||
func (m byDestination) Len() int {
|
||||
|
Reference in New Issue
Block a user