docker/patch/0056-docker-check-cpuset.cpu-and-cpuset.mem.patch
2019-09-30 10:37:25 -04:00

133 lines
3.9 KiB
Diff

From e894ad0fa1c84d1a01afc47ccc52c3556121bbcd Mon Sep 17 00:00:00 2001
From: zhangyu235 <zhangyu235@huawei.com>
Date: Tue, 8 Jan 2019 20:17:21 +0800
Subject: [PATCH 056/111] docker: check cpuset.cpu and cpuset.mem
reason:check cpuset.cpu and cpuset.mem
cherry-pick from docker 1.11.2:
- 1c769f0 check cpuset.cpu and cpuset.mem
Signed-off-by: lujingxiao <lujingxiao@huawei.com>
-----
- 782f78f check cpuset.cpu and cpuset.mem
Signed-off-by: wangyi45 <wangyi45@huawei.com>
Change-Id: If21cad2023d737d03ba3d4a83e62d11fb2297945
Signed-off-by: zhangyu235 <zhangyu235@huawei.com>
---
components/engine/daemon/daemon_unix.go | 2 +
components/engine/pkg/sysinfo/sysinfo.go | 64 +++++++++++++++++++++++-
2 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/components/engine/daemon/daemon_unix.go b/components/engine/daemon/daemon_unix.go
index e48dfcd1ef..b20c66e27b 100644
--- a/components/engine/daemon/daemon_unix.go
+++ b/components/engine/daemon/daemon_unix.go
@@ -499,6 +499,7 @@ func (daemon *Daemon) verifyContainerResources(hostConfig *containertypes.HostCo
}
cpusAvailable, err := sysInfo.IsCpusetCpusAvailable(resources.CpusetCpus)
if err != nil {
+ logrus.Errorf("Checking cpuset.cpus got %#v", err.Error())
return warnings, errors.Wrapf(err, "Invalid value %s for cpuset cpus", resources.CpusetCpus)
}
if !cpusAvailable {
@@ -506,6 +507,7 @@ func (daemon *Daemon) verifyContainerResources(hostConfig *containertypes.HostCo
}
memsAvailable, err := sysInfo.IsCpusetMemsAvailable(resources.CpusetMems)
if err != nil {
+ logrus.Errorf("Checking cpuset.mems got %#v", err.Error())
return warnings, errors.Wrapf(err, "Invalid value %s for cpuset mems", resources.CpusetMems)
}
if !memsAvailable {
diff --git a/components/engine/pkg/sysinfo/sysinfo.go b/components/engine/pkg/sysinfo/sysinfo.go
index 5d9320218c..7ea1be5daf 100644
--- a/components/engine/pkg/sysinfo/sysinfo.go
+++ b/components/engine/pkg/sysinfo/sysinfo.go
@@ -1,6 +1,12 @@
package sysinfo // import "github.com/docker/docker/pkg/sysinfo"
-import "github.com/docker/docker/pkg/parsers"
+import (
+ "fmt"
+ "strconv"
+ "strings"
+
+ "github.com/docker/docker/pkg/parsers"
+)
// SysInfo stores information about which features a kernel supports.
// TODO Windows: Factor out platform specific capabilities.
@@ -123,6 +129,13 @@ func (c cgroupCpusetInfo) IsCpusetMemsAvailable(provided string) (bool, error) {
}
func isCpusetListAvailable(provided, available string) (bool, error) {
+ if err := checkCPU(provided, available); err != nil {
+ if strings.Contains(err.Error(), "invalid format") {
+ return false, err
+ }
+ return false, nil
+ }
+
parsedAvailable, err := parsers.ParseUintList(available)
if err != nil {
return false, err
@@ -147,6 +160,55 @@ func isCpusetListAvailable(provided, available string) (bool, error) {
return true, nil
}
+func checkCPU(provided, available string) error {
+ if provided == "" {
+ return nil
+ }
+
+ maxAvailable, err := maxCPU(available)
+ if err != nil {
+ return err
+ }
+
+ maxRequest, err := maxCPU(provided)
+ if err != nil {
+ return err
+ }
+
+ if maxRequest > maxAvailable {
+ return fmt.Errorf("invalid maxRequest is %d, max available: %d", maxRequest, maxAvailable)
+ }
+
+ return nil
+}
+
+func maxCPU(cores string) (int, error) {
+ var max int
+ split := strings.Split(cores, ",")
+ errInvalidFormat := fmt.Errorf("invalid format: %s", cores)
+ for _, r := range split {
+ if !strings.Contains(r, "-") {
+ v, err := strconv.Atoi(r)
+ if err != nil {
+ return max, errInvalidFormat
+ }
+ if v > max {
+ max = v
+ }
+ } else {
+ split := strings.SplitN(r, "-", 2)
+ end, err := strconv.Atoi(split[1])
+ if err != nil {
+ return max, errInvalidFormat
+ }
+ if end > max {
+ max = end
+ }
+ }
+ }
+ return max, nil
+}
+
// Returns bit count of 1, used by NumCPU
func popcnt(x uint64) (n byte) {
x -= (x >> 1) & 0x5555555555555555
--
2.17.1