podman

Форк
0
/
runtime_pod_linux.go 
149 строк · 5.4 Кб
1
//go:build !remote
2

3
package libpod
4

5
import (
6
	"fmt"
7
	"path"
8
	"path/filepath"
9
	"strings"
10

11
	"github.com/containers/common/pkg/cgroups"
12
	"github.com/containers/common/pkg/config"
13
	"github.com/containers/podman/v5/libpod/define"
14
	"github.com/containers/podman/v5/pkg/rootless"
15
	spec "github.com/opencontainers/runtime-spec/specs-go"
16
	"github.com/sirupsen/logrus"
17
)
18

19
func (r *Runtime) platformMakePod(pod *Pod, resourceLimits *spec.LinuxResources) (string, error) {
20
	cgroupParent := ""
21
	// Check Cgroup parent sanity, and set it if it was not set
22
	if r.config.Cgroups() != "disabled" {
23
		switch r.config.Engine.CgroupManager {
24
		case config.CgroupfsCgroupsManager:
25
			canUseCgroup := !rootless.IsRootless() || isRootlessCgroupSet(pod.config.CgroupParent)
26
			if canUseCgroup {
27
				// need to actually create parent here
28
				if pod.config.CgroupParent == "" {
29
					pod.config.CgroupParent = CgroupfsDefaultCgroupParent
30
				} else if strings.HasSuffix(path.Base(pod.config.CgroupParent), ".slice") {
31
					return "", fmt.Errorf("systemd slice received as cgroup parent when using cgroupfs: %w", define.ErrInvalidArg)
32
				}
33
				// If we are set to use pod cgroups, set the cgroup parent that
34
				// all containers in the pod will share
35
				if pod.config.UsePodCgroup {
36
					pod.state.CgroupPath = filepath.Join(pod.config.CgroupParent, pod.ID())
37
					cgroupParent = pod.state.CgroupPath
38
					// cgroupfs + rootless = permission denied when creating the cgroup.
39
					if !rootless.IsRootless() {
40
						res, err := GetLimits(resourceLimits)
41
						if err != nil {
42
							return "", err
43
						}
44
						res.SkipDevices = true
45
						// Need to both create and update the cgroup
46
						// rather than create a new path in c/common for pod cgroup creation
47
						// just create as if it is a ctr and then update figures out that we need to
48
						// populate the resource limits on the pod level
49
						cgc, err := cgroups.New(pod.state.CgroupPath, &res)
50
						if err != nil {
51
							return "", err
52
						}
53
						err = cgc.Update(&res)
54
						if err != nil {
55
							return "", err
56
						}
57
					}
58
				}
59
			}
60
		case config.SystemdCgroupsManager:
61
			if pod.config.CgroupParent == "" {
62
				if rootless.IsRootless() {
63
					pod.config.CgroupParent = SystemdDefaultRootlessCgroupParent
64
				} else {
65
					pod.config.CgroupParent = SystemdDefaultCgroupParent
66
				}
67
			} else if len(pod.config.CgroupParent) < 6 || !strings.HasSuffix(path.Base(pod.config.CgroupParent), ".slice") {
68
				return "", fmt.Errorf("did not receive systemd slice as cgroup parent when using systemd to manage cgroups: %w", define.ErrInvalidArg)
69
			}
70
			// If we are set to use pod cgroups, set the cgroup parent that
71
			// all containers in the pod will share
72
			if pod.config.UsePodCgroup {
73
				cgroupPath, err := systemdSliceFromPath(pod.config.CgroupParent, fmt.Sprintf("libpod_pod_%s", pod.ID()), resourceLimits)
74
				if err != nil {
75
					return "", fmt.Errorf("unable to create pod cgroup for pod %s: %w", pod.ID(), err)
76
				}
77
				pod.state.CgroupPath = cgroupPath
78
				cgroupParent = pod.state.CgroupPath
79
			}
80
		default:
81
			return "", fmt.Errorf("unsupported Cgroup manager: %s - cannot validate cgroup parent: %w", r.config.Engine.CgroupManager, define.ErrInvalidArg)
82
		}
83
	}
84

85
	if pod.config.UsePodCgroup {
86
		logrus.Debugf("Got pod cgroup as %s", pod.state.CgroupPath)
87
	}
88

89
	return cgroupParent, nil
90
}
91

92
func (p *Pod) removePodCgroup() error {
93
	// Remove pod cgroup, if present
94
	if p.state.CgroupPath == "" {
95
		return nil
96
	}
97
	logrus.Debugf("Removing pod cgroup %s", p.state.CgroupPath)
98

99
	cgroup, err := cgroups.GetOwnCgroup()
100
	if err != nil {
101
		return err
102
	}
103

104
	// if we are trying to delete a cgroup that is our ancestor, we need to move the
105
	// current process out of it before the cgroup is destroyed.
106
	if isSubDir(cgroup, string(filepath.Separator)+p.state.CgroupPath) {
107
		parent := path.Dir(p.state.CgroupPath)
108
		if err := cgroups.MoveUnderCgroup(parent, "cleanup", nil); err != nil {
109
			return err
110
		}
111
	}
112

113
	switch p.runtime.config.Engine.CgroupManager {
114
	case config.SystemdCgroupsManager:
115
		if err := deleteSystemdCgroup(p.state.CgroupPath, p.ResourceLim()); err != nil {
116
			return fmt.Errorf("removing pod %s cgroup: %w", p.ID(), err)
117
		}
118
	case config.CgroupfsCgroupsManager:
119
		// Delete the cgroupfs cgroup
120
		// Make sure the conmon cgroup is deleted first
121
		// Since the pod is almost gone, don't bother failing
122
		// hard - instead, just log errors.
123
		conmonCgroupPath := filepath.Join(p.state.CgroupPath, "conmon")
124
		conmonCgroup, err := cgroups.Load(conmonCgroupPath)
125
		if err != nil && err != cgroups.ErrCgroupDeleted && err != cgroups.ErrCgroupV1Rootless {
126
			return fmt.Errorf("retrieving pod %s conmon cgroup: %w", p.ID(), err)
127
		}
128
		if err == nil {
129
			if err = conmonCgroup.Delete(); err != nil {
130
				return fmt.Errorf("removing pod %s conmon cgroup: %w", p.ID(), err)
131
			}
132
		}
133
		cgroup, err := cgroups.Load(p.state.CgroupPath)
134
		if err != nil && err != cgroups.ErrCgroupDeleted && err != cgroups.ErrCgroupV1Rootless {
135
			return fmt.Errorf("retrieving pod %s cgroup: %w", p.ID(), err)
136
		}
137
		if err == nil {
138
			if err := cgroup.Delete(); err != nil {
139
				return fmt.Errorf("removing pod %s cgroup: %w", p.ID(), err)
140
			}
141
		}
142
	default:
143
		// This should be caught much earlier, but let's still
144
		// keep going so we make sure to evict the pod before
145
		// ending up with an inconsistent state.
146
		return fmt.Errorf("unrecognized cgroup manager %s when removing pod %s cgroups: %w", p.runtime.config.Engine.CgroupManager, p.ID(), define.ErrInternal)
147
	}
148
	return nil
149
}
150

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.