mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
dbb9fc03ae
Only some libcontainer packages can be built on non-linux platforms
(not that it make sense, but at least go build succeeds). Let's call
these "good" packages.
For all other packages (i.e. ones that fail to build with GOOS other
than linux), it does not make sense to have linux build tag (as they
are broken already, and thus are not and can not be used on anything
other than Linux).
Remove linux build tag for all non-"good" packages.
This was mostly done by the following script, with just a few manual
fixes on top.
function list_good_pkgs() {
for pkg in $(find . -type d -print); do
GOOS=freebsd go build $pkg 2>/dev/null \
&& GOOS=solaris go build $pkg 2>/dev/null \
&& echo $pkg
done | sed -e 's|^./||' | tr '\n' '|' | sed -e 's/|$//'
}
function remove_tag() {
sed -i -e '\|^// +build linux$|d' $1
go fmt $1
}
SKIP="^("$(list_good_pkgs)")"
for f in $(git ls-files . | grep .go$); do
if echo $f | grep -qE "$SKIP"; then
echo skip $f
continue
fi
echo proc $f
remove_tag $f
done
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
146 lines
3.8 KiB
Go
146 lines
3.8 KiB
Go
package fscommon
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"math"
|
|
"path"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/opencontainers/runc/libcontainer/cgroups"
|
|
)
|
|
|
|
var (
|
|
// Deprecated: use cgroups.OpenFile instead.
|
|
OpenFile = cgroups.OpenFile
|
|
// Deprecated: use cgroups.ReadFile instead.
|
|
ReadFile = cgroups.ReadFile
|
|
// Deprecated: use cgroups.WriteFile instead.
|
|
WriteFile = cgroups.WriteFile
|
|
)
|
|
|
|
// ParseError records a parse error details, including the file path.
|
|
type ParseError struct {
|
|
Path string
|
|
File string
|
|
Err error
|
|
}
|
|
|
|
func (e *ParseError) Error() string {
|
|
return "unable to parse " + path.Join(e.Path, e.File) + ": " + e.Err.Error()
|
|
}
|
|
|
|
func (e *ParseError) Unwrap() error { return e.Err }
|
|
|
|
// ParseUint converts a string to an uint64 integer.
|
|
// Negative values are returned at zero as, due to kernel bugs,
|
|
// some of the memory cgroup stats can be negative.
|
|
func ParseUint(s string, base, bitSize int) (uint64, error) {
|
|
value, err := strconv.ParseUint(s, base, bitSize)
|
|
if err != nil {
|
|
intValue, intErr := strconv.ParseInt(s, base, bitSize)
|
|
// 1. Handle negative values greater than MinInt64 (and)
|
|
// 2. Handle negative values lesser than MinInt64
|
|
if intErr == nil && intValue < 0 {
|
|
return 0, nil
|
|
} else if errors.Is(intErr, strconv.ErrRange) && intValue < 0 {
|
|
return 0, nil
|
|
}
|
|
|
|
return value, err
|
|
}
|
|
|
|
return value, nil
|
|
}
|
|
|
|
// ParseKeyValue parses a space-separated "name value" kind of cgroup
|
|
// parameter and returns its key as a string, and its value as uint64
|
|
// (ParseUint is used to convert the value). For example,
|
|
// "io_service_bytes 1234" will be returned as "io_service_bytes", 1234.
|
|
func ParseKeyValue(t string) (string, uint64, error) {
|
|
parts := strings.SplitN(t, " ", 3)
|
|
if len(parts) != 2 {
|
|
return "", 0, fmt.Errorf("line %q is not in key value format", t)
|
|
}
|
|
|
|
value, err := ParseUint(parts[1], 10, 64)
|
|
if err != nil {
|
|
return "", 0, err
|
|
}
|
|
|
|
return parts[0], value, nil
|
|
}
|
|
|
|
// GetValueByKey reads a key-value pairs from the specified cgroup file,
|
|
// and returns a value of the specified key. ParseUint is used for value
|
|
// conversion.
|
|
func GetValueByKey(path, file, key string) (uint64, error) {
|
|
content, err := cgroups.ReadFile(path, file)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
lines := strings.Split(content, "\n")
|
|
for _, line := range lines {
|
|
arr := strings.Split(line, " ")
|
|
if len(arr) == 2 && arr[0] == key {
|
|
val, err := ParseUint(arr[1], 10, 64)
|
|
if err != nil {
|
|
err = &ParseError{Path: path, File: file, Err: err}
|
|
}
|
|
return val, err
|
|
}
|
|
}
|
|
|
|
return 0, nil
|
|
}
|
|
|
|
// GetCgroupParamUint reads a single uint64 value from the specified cgroup file.
|
|
// If the value read is "max", the math.MaxUint64 is returned.
|
|
func GetCgroupParamUint(path, file string) (uint64, error) {
|
|
contents, err := GetCgroupParamString(path, file)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
contents = strings.TrimSpace(contents)
|
|
if contents == "max" {
|
|
return math.MaxUint64, nil
|
|
}
|
|
|
|
res, err := ParseUint(contents, 10, 64)
|
|
if err != nil {
|
|
return res, &ParseError{Path: path, File: file, Err: err}
|
|
}
|
|
return res, nil
|
|
}
|
|
|
|
// GetCgroupParamInt reads a single int64 value from specified cgroup file.
|
|
// If the value read is "max", the math.MaxInt64 is returned.
|
|
func GetCgroupParamInt(path, file string) (int64, error) {
|
|
contents, err := cgroups.ReadFile(path, file)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
contents = strings.TrimSpace(contents)
|
|
if contents == "max" {
|
|
return math.MaxInt64, nil
|
|
}
|
|
|
|
res, err := strconv.ParseInt(contents, 10, 64)
|
|
if err != nil {
|
|
return res, &ParseError{Path: path, File: file, Err: err}
|
|
}
|
|
return res, nil
|
|
}
|
|
|
|
// GetCgroupParamString reads a string from the specified cgroup file.
|
|
func GetCgroupParamString(path, file string) (string, error) {
|
|
contents, err := cgroups.ReadFile(path, file)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return strings.TrimSpace(contents), nil
|
|
}
|