diff options
Diffstat (limited to 'runsc/specutils')
-rw-r--r-- | runsc/specutils/BUILD | 1 | ||||
-rw-r--r-- | runsc/specutils/cpu.go | 90 | ||||
-rw-r--r-- | runsc/specutils/specutils.go | 37 |
3 files changed, 37 insertions, 91 deletions
diff --git a/runsc/specutils/BUILD b/runsc/specutils/BUILD index f1a99ce48..e73b2293f 100644 --- a/runsc/specutils/BUILD +++ b/runsc/specutils/BUILD @@ -5,7 +5,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "specutils", srcs = [ - "cpu.go", "namespace.go", "specutils.go", ], diff --git a/runsc/specutils/cpu.go b/runsc/specutils/cpu.go deleted file mode 100644 index 9abe26b64..000000000 --- a/runsc/specutils/cpu.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2018 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package specutils - -import ( - "fmt" - "runtime" - "strconv" - "strings" - - specs "github.com/opencontainers/runtime-spec/specs-go" -) - -// CalculateCPUNumber calculates the number of CPUs that should be exposed -// inside the sandbox. -func CalculateCPUNumber(spec *specs.Spec) (int, error) { - // If spec does not contain CPU field, then return the number of host CPUs. - if spec == nil || spec.Linux == nil || spec.Linux.Resources == nil || spec.Linux.Resources.CPU == nil { - return runtime.NumCPU(), nil - } - cpuSpec := spec.Linux.Resources.CPU - - // If cpuSpec.Cpus is specified, then parse and return that. They must be in - // the list format for cpusets, which is "a comma-separated list of CPU - // numbers and ranges of numbers, in ASCII decimal." --man 7 cpuset. - cpus := cpuSpec.Cpus - if cpus != "" { - cpuNum := 0 - for _, subs := range strings.Split(cpus, ",") { - result, err := parseCPUNumber(subs) - if err != nil { - return 0, err - } - cpuNum += result - } - return cpuNum, nil - } - - // If CPU.Quota and CPU.Period are specified, we can divide them to get an - // approximation of the number of CPUs needed. - if cpuSpec.Quota != nil && cpuSpec.Period != nil && *cpuSpec.Period != 0 { - cpuQuota := *cpuSpec.Quota - cpuPeriod := *cpuSpec.Period - return int(cpuQuota)/int(cpuPeriod) + 1, nil - } - - // Default to number of host cpus. - return runtime.NumCPU(), nil -} - -// parseCPUNumber converts a cpuset string into the number of cpus included in -// the string , e.g. "3-6" -> 4. -func parseCPUNumber(cpus string) (int, error) { - switch cpusSlice := strings.Split(cpus, "-"); len(cpusSlice) { - case 1: - // cpus is not a range. We must only check that it is a valid number. - if _, err := strconv.Atoi(cpus); err != nil { - return 0, fmt.Errorf("invalid individual cpu number %q", cpus) - } - return 1, nil - case 2: - // cpus is a range. We must check that start and end are valid numbers, - // and calculate their difference (inclusively). - first, err := strconv.Atoi(cpusSlice[0]) - if err != nil || first < 0 { - return 0, fmt.Errorf("invalid first cpu number %q in range %q", cpusSlice[0], cpus) - } - last, err := strconv.Atoi(cpusSlice[1]) - if err != nil || last < 0 { - return 0, fmt.Errorf("invalid last cpu number %q in range %q", cpusSlice[1], cpus) - } - cpuNum := last - first + 1 - if cpuNum <= 0 { - return 0, fmt.Errorf("cpu range %q does not include positive number of cpus", cpus) - } - } - return 0, fmt.Errorf("invalid cpu string %q", cpus) -} diff --git a/runsc/specutils/specutils.go b/runsc/specutils/specutils.go index daf10b875..ac017ba2d 100644 --- a/runsc/specutils/specutils.go +++ b/runsc/specutils/specutils.go @@ -43,6 +43,13 @@ func LogSpec(spec *specs.Spec) { log.Debugf("Spec: %+v", spec) log.Debugf("Spec.Hooks: %+v", spec.Hooks) log.Debugf("Spec.Linux: %+v", spec.Linux) + if spec.Linux != nil && spec.Linux.Resources != nil { + res := spec.Linux.Resources + log.Debugf("Spec.Linux.Resources.Memory: %+v", res.Memory) + log.Debugf("Spec.Linux.Resources.CPU: %+v", res.CPU) + log.Debugf("Spec.Linux.Resources.BlockIO: %+v", res.BlockIO) + log.Debugf("Spec.Linux.Resources.Network: %+v", res.Network) + } log.Debugf("Spec.Process: %+v", spec.Process) log.Debugf("Spec.Root: %+v", spec.Root) } @@ -402,3 +409,33 @@ func ContainsStr(strs []string, str string) bool { } return false } + +// Cleanup allows defers to be aborted when cleanup needs to happen +// conditionally. Usage: +// c := MakeCleanup(func() { f.Close() }) +// defer c.Clean() // any failure before release is called will close the file. +// ... +// c.Release() // on success, aborts closing the file and return it. +// return f +type Cleanup struct { + clean func() + released bool +} + +// MakeCleanup creates a new Cleanup object. +func MakeCleanup(f func()) Cleanup { + return Cleanup{clean: f} +} + +// Clean calls the cleanup function. +func (c *Cleanup) Clean() { + if !c.released { + c.clean() + } +} + +// Release releases the cleanup from its duties, i.e. cleanup function is not +// called after this point. +func (c *Cleanup) Release() { + c.released = true +} |