mirror of
https://github.com/optim-enterprises-bv/kubernetes.git
synced 2025-11-25 19:05:13 +00:00
Revert "Merge pull request 101888 from kolyshkin/update-runc-rc94"
This reverts commitb1b06fe0a4, reversing changes made to382a33986b.
This commit is contained in:
20
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/cpu.go
generated
vendored
20
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/cpu.go
generated
vendored
@@ -12,14 +12,15 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
)
|
||||
|
||||
func isCpuSet(r *configs.Resources) bool {
|
||||
return r.CpuWeight != 0 || r.CpuQuota != 0 || r.CpuPeriod != 0
|
||||
func isCpuSet(cgroup *configs.Cgroup) bool {
|
||||
return cgroup.Resources.CpuWeight != 0 || cgroup.Resources.CpuQuota != 0 || cgroup.Resources.CpuPeriod != 0
|
||||
}
|
||||
|
||||
func setCpu(dirPath string, r *configs.Resources) error {
|
||||
if !isCpuSet(r) {
|
||||
func setCpu(dirPath string, cgroup *configs.Cgroup) error {
|
||||
if !isCpuSet(cgroup) {
|
||||
return nil
|
||||
}
|
||||
r := cgroup.Resources
|
||||
|
||||
// NOTE: .CpuShares is not used here. Conversion is the caller's responsibility.
|
||||
if r.CpuWeight != 0 {
|
||||
@@ -56,7 +57,7 @@ func statCpu(dirPath string, stats *cgroups.Stats) error {
|
||||
|
||||
sc := bufio.NewScanner(f)
|
||||
for sc.Scan() {
|
||||
t, v, err := fscommon.ParseKeyValue(sc.Text())
|
||||
t, v, err := fscommon.GetCgroupParamKeyValue(sc.Text())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -69,15 +70,6 @@ func statCpu(dirPath string, stats *cgroups.Stats) error {
|
||||
|
||||
case "system_usec":
|
||||
stats.CpuStats.CpuUsage.UsageInKernelmode = v * 1000
|
||||
|
||||
case "nr_periods":
|
||||
stats.CpuStats.ThrottlingData.Periods = v
|
||||
|
||||
case "nr_throttled":
|
||||
stats.CpuStats.ThrottlingData.ThrottledPeriods = v
|
||||
|
||||
case "throttled_usec":
|
||||
stats.CpuStats.ThrottlingData.ThrottledTime = v * 1000
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
16
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/cpuset.go
generated
vendored
16
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/cpuset.go
generated
vendored
@@ -7,22 +7,22 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
)
|
||||
|
||||
func isCpusetSet(r *configs.Resources) bool {
|
||||
return r.CpusetCpus != "" || r.CpusetMems != ""
|
||||
func isCpusetSet(cgroup *configs.Cgroup) bool {
|
||||
return cgroup.Resources.CpusetCpus != "" || cgroup.Resources.CpusetMems != ""
|
||||
}
|
||||
|
||||
func setCpuset(dirPath string, r *configs.Resources) error {
|
||||
if !isCpusetSet(r) {
|
||||
func setCpuset(dirPath string, cgroup *configs.Cgroup) error {
|
||||
if !isCpusetSet(cgroup) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if r.CpusetCpus != "" {
|
||||
if err := fscommon.WriteFile(dirPath, "cpuset.cpus", r.CpusetCpus); err != nil {
|
||||
if cgroup.Resources.CpusetCpus != "" {
|
||||
if err := fscommon.WriteFile(dirPath, "cpuset.cpus", cgroup.Resources.CpusetCpus); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if r.CpusetMems != "" {
|
||||
if err := fscommon.WriteFile(dirPath, "cpuset.mems", r.CpusetMems); err != nil {
|
||||
if cgroup.Resources.CpusetMems != "" {
|
||||
if err := fscommon.WriteFile(dirPath, "cpuset.mems", cgroup.Resources.CpusetMems); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
30
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/create.go
generated
vendored
30
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/create.go
generated
vendored
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
)
|
||||
|
||||
func supportedControllers() (string, error) {
|
||||
func supportedControllers(cgroup *configs.Cgroup) (string, error) {
|
||||
return fscommon.ReadFile(UnifiedMountpoint, "/cgroup.controllers")
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@ func supportedControllers() (string, error) {
|
||||
// based on (1) controllers available and (2) resources that are being set.
|
||||
// We don't check "pseudo" controllers such as
|
||||
// "freezer" and "devices".
|
||||
func needAnyControllers(r *configs.Resources) (bool, error) {
|
||||
if r == nil {
|
||||
func needAnyControllers(cgroup *configs.Cgroup) (bool, error) {
|
||||
if cgroup == nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// list of all available controllers
|
||||
content, err := supportedControllers()
|
||||
content, err := supportedControllers(cgroup)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -39,22 +39,22 @@ func needAnyControllers(r *configs.Resources) (bool, error) {
|
||||
return ok
|
||||
}
|
||||
|
||||
if isPidsSet(r) && have("pids") {
|
||||
if isPidsSet(cgroup) && have("pids") {
|
||||
return true, nil
|
||||
}
|
||||
if isMemorySet(r) && have("memory") {
|
||||
if isMemorySet(cgroup) && have("memory") {
|
||||
return true, nil
|
||||
}
|
||||
if isIoSet(r) && have("io") {
|
||||
if isIoSet(cgroup) && have("io") {
|
||||
return true, nil
|
||||
}
|
||||
if isCpuSet(r) && have("cpu") {
|
||||
if isCpuSet(cgroup) && have("cpu") {
|
||||
return true, nil
|
||||
}
|
||||
if isCpusetSet(r) && have("cpuset") {
|
||||
if isCpusetSet(cgroup) && have("cpuset") {
|
||||
return true, nil
|
||||
}
|
||||
if isHugeTlbSet(r) && have("hugetlb") {
|
||||
if isHugeTlbSet(cgroup) && have("hugetlb") {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@@ -64,8 +64,8 @@ func needAnyControllers(r *configs.Resources) (bool, error) {
|
||||
// containsDomainController returns whether the current config contains domain controller or not.
|
||||
// Refer to: http://man7.org/linux/man-pages/man7/cgroups.7.html
|
||||
// As at Linux 4.19, the following controllers are threaded: cpu, perf_event, and pids.
|
||||
func containsDomainController(r *configs.Resources) bool {
|
||||
return isMemorySet(r) || isIoSet(r) || isCpuSet(r) || isHugeTlbSet(r)
|
||||
func containsDomainController(cg *configs.Cgroup) bool {
|
||||
return isMemorySet(cg) || isIoSet(cg) || isCpuSet(cg) || isHugeTlbSet(cg)
|
||||
}
|
||||
|
||||
// CreateCgroupPath creates cgroupv2 path, enabling all the supported controllers.
|
||||
@@ -74,7 +74,7 @@ func CreateCgroupPath(path string, c *configs.Cgroup) (Err error) {
|
||||
return fmt.Errorf("invalid cgroup path %s", path)
|
||||
}
|
||||
|
||||
content, err := supportedControllers()
|
||||
content, err := supportedControllers(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -115,7 +115,7 @@ func CreateCgroupPath(path string, c *configs.Cgroup) (Err error) {
|
||||
// the controllers requested are thread-aware we can simply put the cgroup into
|
||||
// threaded mode.
|
||||
case "domain invalid":
|
||||
if containsDomainController(c.Resources) {
|
||||
if containsDomainController(c) {
|
||||
return fmt.Errorf("cannot enter cgroupv2 %q with domain controllers -- it is in an invalid state", current)
|
||||
} else {
|
||||
// Not entirely correct (in theory we'd always want to be a domain --
|
||||
@@ -129,7 +129,7 @@ func CreateCgroupPath(path string, c *configs.Cgroup) (Err error) {
|
||||
case "domain threaded":
|
||||
fallthrough
|
||||
case "threaded":
|
||||
if containsDomainController(c.Resources) {
|
||||
if containsDomainController(c) {
|
||||
return fmt.Errorf("cannot enter cgroupv2 %q with domain controllers -- it is in %s mode", current, cgType)
|
||||
}
|
||||
}
|
||||
|
||||
36
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/devices.go
generated
vendored
36
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/devices.go
generated
vendored
@@ -7,8 +7,6 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/ebpf/devicefilter"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/opencontainers/runc/libcontainer/devices"
|
||||
"github.com/opencontainers/runc/libcontainer/userns"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@@ -28,40 +26,26 @@ func isRWM(perms devices.Permissions) bool {
|
||||
return r && w && m
|
||||
}
|
||||
|
||||
// This is similar to the logic applied in crun for handling errors from bpf(2)
|
||||
// <https://github.com/containers/crun/blob/0.17/src/libcrun/cgroup.c#L2438-L2470>.
|
||||
func canSkipEBPFError(r *configs.Resources) bool {
|
||||
// If we're running in a user namespace we can ignore eBPF rules because we
|
||||
// usually cannot use bpf(2), as well as rootless containers usually don't
|
||||
// have the necessary privileges to mknod(2) device inodes or access
|
||||
// host-level instances (though ideally we would be blocking device access
|
||||
// for rootless containers anyway).
|
||||
if userns.RunningInUserNS() {
|
||||
return true
|
||||
}
|
||||
|
||||
// We cannot ignore an eBPF load error if any rule if is a block rule or it
|
||||
// doesn't permit all access modes.
|
||||
//
|
||||
// NOTE: This will sometimes trigger in cases where access modes are split
|
||||
// between different rules but to handle this correctly would require
|
||||
// using ".../libcontainer/cgroup/devices".Emulator.
|
||||
for _, dev := range r.Devices {
|
||||
if !dev.Allow || !isRWM(dev.Permissions) {
|
||||
// the logic is from crun
|
||||
// https://github.com/containers/crun/blob/0.10.2/src/libcrun/cgroup.c#L1644-L1652
|
||||
func canSkipEBPFError(cgroup *configs.Cgroup) bool {
|
||||
for _, dev := range cgroup.Resources.Devices {
|
||||
if dev.Allow || !isRWM(dev.Permissions) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func setDevices(dirPath string, r *configs.Resources) error {
|
||||
if r.SkipDevices {
|
||||
func setDevices(dirPath string, cgroup *configs.Cgroup) error {
|
||||
if cgroup.SkipDevices {
|
||||
return nil
|
||||
}
|
||||
// XXX: This is currently a white-list (but all callers pass a blacklist of
|
||||
// devices). This is bad for a whole variety of reasons, but will need
|
||||
// to be fixed with co-ordinated effort with downstreams.
|
||||
insts, license, err := devicefilter.DeviceFilter(r.Devices)
|
||||
devices := cgroup.Devices
|
||||
insts, license, err := devicefilter.DeviceFilter(devices)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -82,7 +66,7 @@ func setDevices(dirPath string, r *configs.Resources) error {
|
||||
// programs. You could temporarily insert a deny-everything program
|
||||
// but that would result in spurrious failures during updates.
|
||||
if _, err := ebpf.LoadAttachCgroupDeviceFilter(insts, license, dirFD); err != nil {
|
||||
if !canSkipEBPFError(r) {
|
||||
if !canSkipEBPFError(cgroup) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
80
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/fs2.go
generated
vendored
80
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/fs2.go
generated
vendored
@@ -75,7 +75,7 @@ func (m *manager) Apply(pid int) error {
|
||||
// - "runc create (rootless + limits + no cgrouppath + no permission) fails with informative error"
|
||||
if m.rootless {
|
||||
if m.config.Path == "" {
|
||||
if blNeed, nErr := needAnyControllers(m.config.Resources); nErr == nil && !blNeed {
|
||||
if blNeed, nErr := needAnyControllers(m.config); nErr == nil && !blNeed {
|
||||
return nil
|
||||
}
|
||||
return errors.Wrap(err, "rootless needs no limits + no cgrouppath when no permission is granted for cgroups")
|
||||
@@ -103,27 +103,43 @@ func (m *manager) GetStats() (*cgroups.Stats, error) {
|
||||
)
|
||||
|
||||
st := cgroups.NewStats()
|
||||
if err := m.getControllers(); err != nil {
|
||||
return st, err
|
||||
}
|
||||
|
||||
// pids (since kernel 4.5)
|
||||
if err := statPids(m.dirPath, st); err != nil {
|
||||
errs = append(errs, err)
|
||||
if _, ok := m.controllers["pids"]; ok {
|
||||
if err := statPids(m.dirPath, st); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
} else {
|
||||
if err := statPidsWithoutController(m.dirPath, st); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
// memory (since kernel 4.5)
|
||||
if err := statMemory(m.dirPath, st); err != nil && !os.IsNotExist(err) {
|
||||
errs = append(errs, err)
|
||||
if _, ok := m.controllers["memory"]; ok {
|
||||
if err := statMemory(m.dirPath, st); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
// io (since kernel 4.5)
|
||||
if err := statIo(m.dirPath, st); err != nil && !os.IsNotExist(err) {
|
||||
errs = append(errs, err)
|
||||
if _, ok := m.controllers["io"]; ok {
|
||||
if err := statIo(m.dirPath, st); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
// cpu (since kernel 4.15)
|
||||
// Note cpu.stat is available even if the controller is not enabled.
|
||||
if err := statCpu(m.dirPath, st); err != nil && !os.IsNotExist(err) {
|
||||
errs = append(errs, err)
|
||||
if _, ok := m.controllers["cpu"]; ok {
|
||||
if err := statCpu(m.dirPath, st); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
// hugetlb (since kernel 5.6)
|
||||
if err := statHugeTlb(m.dirPath, st); err != nil && !os.IsNotExist(err) {
|
||||
errs = append(errs, err)
|
||||
if _, ok := m.controllers["hugetlb"]; ok {
|
||||
if err := statHugeTlb(m.dirPath, st); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
if len(errs) > 0 && !m.rootless {
|
||||
return st, errors.Errorf("error while statting cgroup v2: %+v", errs)
|
||||
@@ -147,50 +163,53 @@ func (m *manager) Path(_ string) string {
|
||||
return m.dirPath
|
||||
}
|
||||
|
||||
func (m *manager) Set(r *configs.Resources) error {
|
||||
func (m *manager) Set(container *configs.Config) error {
|
||||
if container == nil || container.Cgroups == nil {
|
||||
return nil
|
||||
}
|
||||
if err := m.getControllers(); err != nil {
|
||||
return err
|
||||
}
|
||||
// pids (since kernel 4.5)
|
||||
if err := setPids(m.dirPath, r); err != nil {
|
||||
if err := setPids(m.dirPath, container.Cgroups); err != nil {
|
||||
return err
|
||||
}
|
||||
// memory (since kernel 4.5)
|
||||
if err := setMemory(m.dirPath, r); err != nil {
|
||||
if err := setMemory(m.dirPath, container.Cgroups); err != nil {
|
||||
return err
|
||||
}
|
||||
// io (since kernel 4.5)
|
||||
if err := setIo(m.dirPath, r); err != nil {
|
||||
if err := setIo(m.dirPath, container.Cgroups); err != nil {
|
||||
return err
|
||||
}
|
||||
// cpu (since kernel 4.15)
|
||||
if err := setCpu(m.dirPath, r); err != nil {
|
||||
if err := setCpu(m.dirPath, container.Cgroups); err != nil {
|
||||
return err
|
||||
}
|
||||
// devices (since kernel 4.15, pseudo-controller)
|
||||
//
|
||||
// When m.rootless is true, errors from the device subsystem are ignored because it is really not expected to work.
|
||||
// When m.Rootless is true, errors from the device subsystem are ignored because it is really not expected to work.
|
||||
// However, errors from other subsystems are not ignored.
|
||||
// see @test "runc create (rootless + limits + no cgrouppath + no permission) fails with informative error"
|
||||
if err := setDevices(m.dirPath, r); err != nil && !m.rootless {
|
||||
if err := setDevices(m.dirPath, container.Cgroups); err != nil && !m.rootless {
|
||||
return err
|
||||
}
|
||||
// cpuset (since kernel 5.0)
|
||||
if err := setCpuset(m.dirPath, r); err != nil {
|
||||
if err := setCpuset(m.dirPath, container.Cgroups); err != nil {
|
||||
return err
|
||||
}
|
||||
// hugetlb (since kernel 5.6)
|
||||
if err := setHugeTlb(m.dirPath, r); err != nil {
|
||||
if err := setHugeTlb(m.dirPath, container.Cgroups); err != nil {
|
||||
return err
|
||||
}
|
||||
// freezer (since kernel 5.2, pseudo-controller)
|
||||
if err := setFreezer(m.dirPath, r.Freezer); err != nil {
|
||||
if err := setFreezer(m.dirPath, container.Cgroups.Freezer); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := m.setUnified(r.Unified); err != nil {
|
||||
if err := m.setUnified(container.Cgroups.Unified); err != nil {
|
||||
return err
|
||||
}
|
||||
m.config.Resources = r
|
||||
m.config = container.Cgroups
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -238,16 +257,3 @@ func (m *manager) GetFreezerState() (configs.FreezerState, error) {
|
||||
func (m *manager) Exists() bool {
|
||||
return cgroups.PathExists(m.dirPath)
|
||||
}
|
||||
|
||||
func OOMKillCount(path string) (uint64, error) {
|
||||
return fscommon.GetValueByKey(path, "memory.events", "oom_kill")
|
||||
}
|
||||
|
||||
func (m *manager) OOMKillCount() (uint64, error) {
|
||||
c, err := OOMKillCount(m.dirPath)
|
||||
if err != nil && m.rootless && os.IsNotExist(err) {
|
||||
err = nil
|
||||
}
|
||||
|
||||
return c, err
|
||||
}
|
||||
|
||||
16
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/hugetlb.go
generated
vendored
16
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/hugetlb.go
generated
vendored
@@ -12,15 +12,15 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
)
|
||||
|
||||
func isHugeTlbSet(r *configs.Resources) bool {
|
||||
return len(r.HugetlbLimit) > 0
|
||||
func isHugeTlbSet(cgroup *configs.Cgroup) bool {
|
||||
return len(cgroup.Resources.HugetlbLimit) > 0
|
||||
}
|
||||
|
||||
func setHugeTlb(dirPath string, r *configs.Resources) error {
|
||||
if !isHugeTlbSet(r) {
|
||||
func setHugeTlb(dirPath string, cgroup *configs.Cgroup) error {
|
||||
if !isHugeTlbSet(cgroup) {
|
||||
return nil
|
||||
}
|
||||
for _, hugetlb := range r.HugetlbLimit {
|
||||
for _, hugetlb := range cgroup.Resources.HugetlbLimit {
|
||||
if err := fscommon.WriteFile(dirPath, "hugetlb."+hugetlb.Pagesize+".max", strconv.FormatUint(hugetlb.Limit, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -44,10 +44,14 @@ func statHugeTlb(dirPath string, stats *cgroups.Stats) error {
|
||||
hugetlbStats.Usage = value
|
||||
|
||||
fileName := "hugetlb." + pagesize + ".events"
|
||||
value, err = fscommon.GetValueByKey(dirPath, fileName, "max")
|
||||
contents, err := fscommon.ReadFile(dirPath, fileName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to read stats")
|
||||
}
|
||||
_, value, err = fscommon.GetCgroupParamKeyValue(contents)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse "+fileName)
|
||||
}
|
||||
hugetlbStats.Failcnt = value
|
||||
|
||||
stats.HugetlbStats[pagesize] = hugetlbStats
|
||||
|
||||
38
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/io.go
generated
vendored
38
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/io.go
generated
vendored
@@ -13,50 +13,42 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
)
|
||||
|
||||
func isIoSet(r *configs.Resources) bool {
|
||||
return r.BlkioWeight != 0 ||
|
||||
len(r.BlkioThrottleReadBpsDevice) > 0 ||
|
||||
len(r.BlkioThrottleWriteBpsDevice) > 0 ||
|
||||
len(r.BlkioThrottleReadIOPSDevice) > 0 ||
|
||||
len(r.BlkioThrottleWriteIOPSDevice) > 0
|
||||
func isIoSet(cgroup *configs.Cgroup) bool {
|
||||
return cgroup.Resources.BlkioWeight != 0 ||
|
||||
len(cgroup.Resources.BlkioThrottleReadBpsDevice) > 0 ||
|
||||
len(cgroup.Resources.BlkioThrottleWriteBpsDevice) > 0 ||
|
||||
len(cgroup.Resources.BlkioThrottleReadIOPSDevice) > 0 ||
|
||||
len(cgroup.Resources.BlkioThrottleWriteIOPSDevice) > 0
|
||||
}
|
||||
|
||||
func setIo(dirPath string, r *configs.Resources) error {
|
||||
if !isIoSet(r) {
|
||||
func setIo(dirPath string, cgroup *configs.Cgroup) error {
|
||||
if !isIoSet(cgroup) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if r.BlkioWeight != 0 {
|
||||
if cgroup.Resources.BlkioWeight != 0 {
|
||||
filename := "io.bfq.weight"
|
||||
if err := fscommon.WriteFile(dirPath, filename,
|
||||
strconv.FormatUint(uint64(r.BlkioWeight), 10)); err != nil {
|
||||
// if io.bfq.weight does not exist, then bfq module is not loaded.
|
||||
// Fallback to use io.weight with a conversion scheme
|
||||
if !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
v := cgroups.ConvertBlkIOToIOWeightValue(r.BlkioWeight)
|
||||
if err := fscommon.WriteFile(dirPath, "io.weight", strconv.FormatUint(v, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
strconv.FormatUint(cgroups.ConvertBlkIOToCgroupV2Value(cgroup.Resources.BlkioWeight), 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, td := range r.BlkioThrottleReadBpsDevice {
|
||||
for _, td := range cgroup.Resources.BlkioThrottleReadBpsDevice {
|
||||
if err := fscommon.WriteFile(dirPath, "io.max", td.StringName("rbps")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, td := range r.BlkioThrottleWriteBpsDevice {
|
||||
for _, td := range cgroup.Resources.BlkioThrottleWriteBpsDevice {
|
||||
if err := fscommon.WriteFile(dirPath, "io.max", td.StringName("wbps")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, td := range r.BlkioThrottleReadIOPSDevice {
|
||||
for _, td := range cgroup.Resources.BlkioThrottleReadIOPSDevice {
|
||||
if err := fscommon.WriteFile(dirPath, "io.max", td.StringName("riops")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, td := range r.BlkioThrottleWriteIOPSDevice {
|
||||
for _, td := range cgroup.Resources.BlkioThrottleWriteIOPSDevice {
|
||||
if err := fscommon.WriteFile(dirPath, "io.max", td.StringName("wiops")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
108
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/memory.go
generated
vendored
108
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/memory.go
generated
vendored
@@ -4,16 +4,13 @@ package fs2
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"math"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// numToStr converts an int64 value to a string for writing to a
|
||||
@@ -33,20 +30,21 @@ func numToStr(value int64) (ret string) {
|
||||
return ret
|
||||
}
|
||||
|
||||
func isMemorySet(r *configs.Resources) bool {
|
||||
return r.MemoryReservation != 0 || r.Memory != 0 || r.MemorySwap != 0
|
||||
func isMemorySet(cgroup *configs.Cgroup) bool {
|
||||
return cgroup.Resources.MemoryReservation != 0 ||
|
||||
cgroup.Resources.Memory != 0 || cgroup.Resources.MemorySwap != 0
|
||||
}
|
||||
|
||||
func setMemory(dirPath string, r *configs.Resources) error {
|
||||
if !isMemorySet(r) {
|
||||
func setMemory(dirPath string, cgroup *configs.Cgroup) error {
|
||||
if !isMemorySet(cgroup) {
|
||||
return nil
|
||||
}
|
||||
swap, err := cgroups.ConvertMemorySwapToCgroupV2Value(r.MemorySwap, r.Memory)
|
||||
swap, err := cgroups.ConvertMemorySwapToCgroupV2Value(cgroup.Resources.MemorySwap, cgroup.Resources.Memory)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
swapStr := numToStr(swap)
|
||||
if swapStr == "" && swap == 0 && r.MemorySwap > 0 {
|
||||
if swapStr == "" && swap == 0 && cgroup.Resources.MemorySwap > 0 {
|
||||
// memory and memorySwap set to the same value -- disable swap
|
||||
swapStr = "0"
|
||||
}
|
||||
@@ -57,7 +55,7 @@ func setMemory(dirPath string, r *configs.Resources) error {
|
||||
}
|
||||
}
|
||||
|
||||
if val := numToStr(r.Memory); val != "" {
|
||||
if val := numToStr(cgroup.Resources.Memory); val != "" {
|
||||
if err := fscommon.WriteFile(dirPath, "memory.max", val); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -65,7 +63,7 @@ func setMemory(dirPath string, r *configs.Resources) error {
|
||||
|
||||
// cgroup.Resources.KernelMemory is ignored
|
||||
|
||||
if val := numToStr(r.MemoryReservation); val != "" {
|
||||
if val := numToStr(cgroup.Resources.MemoryReservation); val != "" {
|
||||
if err := fscommon.WriteFile(dirPath, "memory.low", val); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -84,24 +82,16 @@ func statMemory(dirPath string, stats *cgroups.Stats) error {
|
||||
|
||||
sc := bufio.NewScanner(statsFile)
|
||||
for sc.Scan() {
|
||||
t, v, err := fscommon.ParseKeyValue(sc.Text())
|
||||
t, v, err := fscommon.GetCgroupParamKeyValue(sc.Text())
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse memory.stat (%q)", sc.Text())
|
||||
}
|
||||
stats.MemoryStats.Stats[t] = v
|
||||
}
|
||||
stats.MemoryStats.Cache = stats.MemoryStats.Stats["file"]
|
||||
// Unlike cgroup v1 which has memory.use_hierarchy binary knob,
|
||||
// cgroup v2 is always hierarchical.
|
||||
stats.MemoryStats.UseHierarchy = true
|
||||
stats.MemoryStats.Cache = stats.MemoryStats.Stats["cache"]
|
||||
|
||||
memoryUsage, err := getMemoryDataV2(dirPath, "")
|
||||
if err != nil {
|
||||
if errors.Is(err, unix.ENOENT) && dirPath == UnifiedMountpoint {
|
||||
// The root cgroup does not have memory.{current,max}
|
||||
// so emulate those using data from /proc/meminfo.
|
||||
return statsFromMeminfo(stats)
|
||||
}
|
||||
return err
|
||||
}
|
||||
stats.MemoryStats.Usage = memoryUsage
|
||||
@@ -109,15 +99,9 @@ func statMemory(dirPath string, stats *cgroups.Stats) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// As cgroup v1 reports SwapUsage values as mem+swap combined,
|
||||
// while in cgroup v2 swap values do not include memory,
|
||||
// report combined mem+swap for v1 compatibility.
|
||||
swapUsage.Usage += memoryUsage.Usage
|
||||
if swapUsage.Limit != math.MaxUint64 {
|
||||
swapUsage.Limit += memoryUsage.Limit
|
||||
}
|
||||
stats.MemoryStats.SwapUsage = swapUsage
|
||||
|
||||
stats.MemoryStats.UseHierarchy = true
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -133,10 +117,7 @@ func getMemoryDataV2(path, name string) (cgroups.MemoryData, error) {
|
||||
|
||||
value, err := fscommon.GetCgroupParamUint(path, usage)
|
||||
if err != nil {
|
||||
if name != "" && os.IsNotExist(err) {
|
||||
// Ignore EEXIST as there's no swap accounting
|
||||
// if kernel CONFIG_MEMCG_SWAP is not set or
|
||||
// swapaccount=0 kernel boot parameter is given.
|
||||
if moduleName != "memory" && os.IsNotExist(err) {
|
||||
return cgroups.MemoryData{}, nil
|
||||
}
|
||||
return cgroups.MemoryData{}, errors.Wrapf(err, "failed to parse %s", usage)
|
||||
@@ -145,69 +126,12 @@ func getMemoryDataV2(path, name string) (cgroups.MemoryData, error) {
|
||||
|
||||
value, err = fscommon.GetCgroupParamUint(path, limit)
|
||||
if err != nil {
|
||||
if moduleName != "memory" && os.IsNotExist(err) {
|
||||
return cgroups.MemoryData{}, nil
|
||||
}
|
||||
return cgroups.MemoryData{}, errors.Wrapf(err, "failed to parse %s", limit)
|
||||
}
|
||||
memoryData.Limit = value
|
||||
|
||||
return memoryData, nil
|
||||
}
|
||||
|
||||
func statsFromMeminfo(stats *cgroups.Stats) error {
|
||||
f, err := os.Open("/proc/meminfo")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// Fields we are interested in.
|
||||
var (
|
||||
swap_free uint64
|
||||
swap_total uint64
|
||||
main_total uint64
|
||||
main_free uint64
|
||||
)
|
||||
mem := map[string]*uint64{
|
||||
"SwapFree": &swap_free,
|
||||
"SwapTotal": &swap_total,
|
||||
"MemTotal": &main_total,
|
||||
"MemFree": &main_free,
|
||||
}
|
||||
|
||||
found := 0
|
||||
sc := bufio.NewScanner(f)
|
||||
for sc.Scan() {
|
||||
parts := strings.SplitN(sc.Text(), ":", 3)
|
||||
if len(parts) != 2 {
|
||||
// Should not happen.
|
||||
continue
|
||||
}
|
||||
k := parts[0]
|
||||
p, ok := mem[k]
|
||||
if !ok {
|
||||
// Unknown field -- not interested.
|
||||
continue
|
||||
}
|
||||
vStr := strings.TrimSpace(strings.TrimSuffix(parts[1], " kB"))
|
||||
*p, err = strconv.ParseUint(vStr, 10, 64)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "parsing /proc/meminfo "+k)
|
||||
}
|
||||
|
||||
found++
|
||||
if found == len(mem) {
|
||||
// Got everything we need -- skip the rest.
|
||||
break
|
||||
}
|
||||
}
|
||||
if sc.Err() != nil {
|
||||
return sc.Err()
|
||||
}
|
||||
|
||||
stats.MemoryStats.SwapUsage.Usage = (swap_total - swap_free) * 1024
|
||||
stats.MemoryStats.SwapUsage.Limit = math.MaxUint64
|
||||
|
||||
stats.MemoryStats.Usage.Usage = (main_total - main_free) * 1024
|
||||
stats.MemoryStats.Usage.Limit = math.MaxUint64
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
25
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/pids.go
generated
vendored
25
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/pids.go
generated
vendored
@@ -3,7 +3,6 @@
|
||||
package fs2
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -14,15 +13,15 @@ import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func isPidsSet(r *configs.Resources) bool {
|
||||
return r.PidsLimit != 0
|
||||
func isPidsSet(cgroup *configs.Cgroup) bool {
|
||||
return cgroup.Resources.PidsLimit != 0
|
||||
}
|
||||
|
||||
func setPids(dirPath string, r *configs.Resources) error {
|
||||
if !isPidsSet(r) {
|
||||
func setPids(dirPath string, cgroup *configs.Cgroup) error {
|
||||
if !isPidsSet(cgroup) {
|
||||
return nil
|
||||
}
|
||||
if val := numToStr(r.PidsLimit); val != "" {
|
||||
if val := numToStr(cgroup.Resources.PidsLimit); val != "" {
|
||||
if err := fscommon.WriteFile(dirPath, "pids.max", val); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -31,7 +30,7 @@ func setPids(dirPath string, r *configs.Resources) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func statPidsFromCgroupProcs(dirPath string, stats *cgroups.Stats) error {
|
||||
func statPidsWithoutController(dirPath string, stats *cgroups.Stats) error {
|
||||
// if the controller is not enabled, let's read PIDS from cgroups.procs
|
||||
// (or threads if cgroup.threads is enabled)
|
||||
contents, err := fscommon.ReadFile(dirPath, "cgroup.procs")
|
||||
@@ -41,8 +40,13 @@ func statPidsFromCgroupProcs(dirPath string, stats *cgroups.Stats) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pids := strings.Count(contents, "\n")
|
||||
stats.PidsStats.Current = uint64(pids)
|
||||
pids := make(map[string]string)
|
||||
for _, i := range strings.Split(contents, "\n") {
|
||||
if i != "" {
|
||||
pids[i] = i
|
||||
}
|
||||
}
|
||||
stats.PidsStats.Current = uint64(len(pids))
|
||||
stats.PidsStats.Limit = 0
|
||||
return nil
|
||||
}
|
||||
@@ -50,9 +54,6 @@ func statPidsFromCgroupProcs(dirPath string, stats *cgroups.Stats) error {
|
||||
func statPids(dirPath string, stats *cgroups.Stats) error {
|
||||
current, err := fscommon.GetCgroupParamUint(dirPath, "pids.current")
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return statPidsFromCgroupProcs(dirPath, stats)
|
||||
}
|
||||
return errors.Wrap(err, "failed to parse pids.current")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user