mirror of
				https://github.com/containers/podman.git
				synced 2025-10-30 17:38:27 +08:00 
			
		
		
		
	 72f1617fac
			
		
	
	72f1617fac
	
	
	
		
			
			Moving from Go module v4 to v5 prepares us for public releases. Move done using gomove [1] as with the v3 and v4 moves. [1] https://github.com/KSubedi/gomove Signed-off-by: Matt Heon <mheon@redhat.com>
		
			
				
	
	
		
			150 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			150 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| //go:build !remote
 | |
| 
 | |
| package libpod
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"path"
 | |
| 	"path/filepath"
 | |
| 	"strings"
 | |
| 
 | |
| 	"github.com/containers/common/pkg/cgroups"
 | |
| 	"github.com/containers/common/pkg/config"
 | |
| 	"github.com/containers/podman/v5/libpod/define"
 | |
| 	"github.com/containers/podman/v5/pkg/rootless"
 | |
| 	spec "github.com/opencontainers/runtime-spec/specs-go"
 | |
| 	"github.com/sirupsen/logrus"
 | |
| )
 | |
| 
 | |
| func (r *Runtime) platformMakePod(pod *Pod, resourceLimits *spec.LinuxResources) (string, error) {
 | |
| 	cgroupParent := ""
 | |
| 	// Check Cgroup parent sanity, and set it if it was not set
 | |
| 	if r.config.Cgroups() != "disabled" {
 | |
| 		switch r.config.Engine.CgroupManager {
 | |
| 		case config.CgroupfsCgroupsManager:
 | |
| 			canUseCgroup := !rootless.IsRootless() || isRootlessCgroupSet(pod.config.CgroupParent)
 | |
| 			if canUseCgroup {
 | |
| 				// need to actually create parent here
 | |
| 				if pod.config.CgroupParent == "" {
 | |
| 					pod.config.CgroupParent = CgroupfsDefaultCgroupParent
 | |
| 				} else if strings.HasSuffix(path.Base(pod.config.CgroupParent), ".slice") {
 | |
| 					return "", fmt.Errorf("systemd slice received as cgroup parent when using cgroupfs: %w", define.ErrInvalidArg)
 | |
| 				}
 | |
| 				// If we are set to use pod cgroups, set the cgroup parent that
 | |
| 				// all containers in the pod will share
 | |
| 				if pod.config.UsePodCgroup {
 | |
| 					pod.state.CgroupPath = filepath.Join(pod.config.CgroupParent, pod.ID())
 | |
| 					cgroupParent = pod.state.CgroupPath
 | |
| 					// cgroupfs + rootless = permission denied when creating the cgroup.
 | |
| 					if !rootless.IsRootless() {
 | |
| 						res, err := GetLimits(resourceLimits)
 | |
| 						if err != nil {
 | |
| 							return "", err
 | |
| 						}
 | |
| 						res.SkipDevices = true
 | |
| 						// Need to both create and update the cgroup
 | |
| 						// rather than create a new path in c/common for pod cgroup creation
 | |
| 						// just create as if it is a ctr and then update figures out that we need to
 | |
| 						// populate the resource limits on the pod level
 | |
| 						cgc, err := cgroups.New(pod.state.CgroupPath, &res)
 | |
| 						if err != nil {
 | |
| 							return "", err
 | |
| 						}
 | |
| 						err = cgc.Update(&res)
 | |
| 						if err != nil {
 | |
| 							return "", err
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		case config.SystemdCgroupsManager:
 | |
| 			if pod.config.CgroupParent == "" {
 | |
| 				if rootless.IsRootless() {
 | |
| 					pod.config.CgroupParent = SystemdDefaultRootlessCgroupParent
 | |
| 				} else {
 | |
| 					pod.config.CgroupParent = SystemdDefaultCgroupParent
 | |
| 				}
 | |
| 			} else if len(pod.config.CgroupParent) < 6 || !strings.HasSuffix(path.Base(pod.config.CgroupParent), ".slice") {
 | |
| 				return "", fmt.Errorf("did not receive systemd slice as cgroup parent when using systemd to manage cgroups: %w", define.ErrInvalidArg)
 | |
| 			}
 | |
| 			// 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()), resourceLimits)
 | |
| 				if err != nil {
 | |
| 					return "", fmt.Errorf("unable to create pod cgroup for pod %s: %w", pod.ID(), err)
 | |
| 				}
 | |
| 				pod.state.CgroupPath = cgroupPath
 | |
| 				cgroupParent = pod.state.CgroupPath
 | |
| 			}
 | |
| 		default:
 | |
| 			return "", fmt.Errorf("unsupported Cgroup manager: %s - cannot validate cgroup parent: %w", r.config.Engine.CgroupManager, define.ErrInvalidArg)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if pod.config.UsePodCgroup {
 | |
| 		logrus.Debugf("Got pod cgroup as %s", pod.state.CgroupPath)
 | |
| 	}
 | |
| 
 | |
| 	return cgroupParent, nil
 | |
| }
 | |
| 
 | |
| func (p *Pod) removePodCgroup() error {
 | |
| 	// Remove pod cgroup, if present
 | |
| 	if p.state.CgroupPath == "" {
 | |
| 		return nil
 | |
| 	}
 | |
| 	logrus.Debugf("Removing pod cgroup %s", p.state.CgroupPath)
 | |
| 
 | |
| 	cgroup, err := cgroups.GetOwnCgroup()
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	// if we are trying to delete a cgroup that is our ancestor, we need to move the
 | |
| 	// current process out of it before the cgroup is destroyed.
 | |
| 	if isSubDir(cgroup, string(filepath.Separator)+p.state.CgroupPath) {
 | |
| 		parent := path.Dir(p.state.CgroupPath)
 | |
| 		if err := cgroups.MoveUnderCgroup(parent, "cleanup", nil); err != nil {
 | |
| 			return err
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	switch p.runtime.config.Engine.CgroupManager {
 | |
| 	case config.SystemdCgroupsManager:
 | |
| 		if err := deleteSystemdCgroup(p.state.CgroupPath, p.ResourceLim()); err != nil {
 | |
| 			return fmt.Errorf("removing pod %s cgroup: %w", p.ID(), err)
 | |
| 		}
 | |
| 	case config.CgroupfsCgroupsManager:
 | |
| 		// Delete the cgroupfs cgroup
 | |
| 		// Make sure the conmon cgroup is deleted first
 | |
| 		// Since the pod is almost gone, don't bother failing
 | |
| 		// hard - instead, just log errors.
 | |
| 		conmonCgroupPath := filepath.Join(p.state.CgroupPath, "conmon")
 | |
| 		conmonCgroup, err := cgroups.Load(conmonCgroupPath)
 | |
| 		if err != nil && err != cgroups.ErrCgroupDeleted && err != cgroups.ErrCgroupV1Rootless {
 | |
| 			return fmt.Errorf("retrieving pod %s conmon cgroup: %w", p.ID(), err)
 | |
| 		}
 | |
| 		if err == nil {
 | |
| 			if err = conmonCgroup.Delete(); err != nil {
 | |
| 				return fmt.Errorf("removing pod %s conmon cgroup: %w", p.ID(), err)
 | |
| 			}
 | |
| 		}
 | |
| 		cgroup, err := cgroups.Load(p.state.CgroupPath)
 | |
| 		if err != nil && err != cgroups.ErrCgroupDeleted && err != cgroups.ErrCgroupV1Rootless {
 | |
| 			return fmt.Errorf("retrieving pod %s cgroup: %w", p.ID(), err)
 | |
| 		}
 | |
| 		if err == nil {
 | |
| 			if err := cgroup.Delete(); err != nil {
 | |
| 				return fmt.Errorf("removing pod %s cgroup: %w", p.ID(), err)
 | |
| 			}
 | |
| 		}
 | |
| 	default:
 | |
| 		// This should be caught much earlier, but let's still
 | |
| 		// keep going so we make sure to evict the pod before
 | |
| 		// ending up with an inconsistent state.
 | |
| 		return fmt.Errorf("unrecognized cgroup manager %s when removing pod %s cgroups: %w", p.runtime.config.Engine.CgroupManager, p.ID(), define.ErrInternal)
 | |
| 	}
 | |
| 	return nil
 | |
| }
 |