github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/libcontainer/cgroups/fs/utils.go (about)

     1  // +build linux
     2  
     3  package fs
     4  
     5  import (
     6  	"errors"
     7  	"fmt"
     8  	"io/ioutil"
     9  	"path/filepath"
    10  	"strconv"
    11  	"strings"
    12  )
    13  
    14  var (
    15  	ErrNotValidFormat = errors.New("line is not a valid key value format")
    16  )
    17  
    18  // Saturates negative values at zero and returns a uint64.
    19  // Due to kernel bugs, some of the memory cgroup stats can be negative.
    20  func parseUint(s string, base, bitSize int) (uint64, error) {
    21  	value, err := strconv.ParseUint(s, base, bitSize)
    22  	if err != nil {
    23  		intValue, intErr := strconv.ParseInt(s, base, bitSize)
    24  		// 1. Handle negative values greater than MinInt64 (and)
    25  		// 2. Handle negative values lesser than MinInt64
    26  		if intErr == nil && intValue < 0 {
    27  			return 0, nil
    28  		} else if intErr != nil && intErr.(*strconv.NumError).Err == strconv.ErrRange && intValue < 0 {
    29  			return 0, nil
    30  		}
    31  
    32  		return value, err
    33  	}
    34  
    35  	return value, nil
    36  }
    37  
    38  // Parses a cgroup param and returns as name, value
    39  //  i.e. "io_service_bytes 1234" will return as io_service_bytes, 1234
    40  func getCgroupParamKeyValue(t string) (string, uint64, error) {
    41  	parts := strings.Fields(t)
    42  	switch len(parts) {
    43  	case 2:
    44  		value, err := parseUint(parts[1], 10, 64)
    45  		if err != nil {
    46  			return "", 0, fmt.Errorf("unable to convert param value (%q) to uint64: %v", parts[1], err)
    47  		}
    48  
    49  		return parts[0], value, nil
    50  	default:
    51  		return "", 0, ErrNotValidFormat
    52  	}
    53  }
    54  
    55  // Gets a single uint64 value from the specified cgroup file.
    56  func getCgroupParamUint(cgroupPath, cgroupFile string) (uint64, error) {
    57  	fileName := filepath.Join(cgroupPath, cgroupFile)
    58  	contents, err := ioutil.ReadFile(fileName)
    59  	if err != nil {
    60  		return 0, err
    61  	}
    62  
    63  	res, err := parseUint(strings.TrimSpace(string(contents)), 10, 64)
    64  	if err != nil {
    65  		return res, fmt.Errorf("unable to parse %q as a uint from Cgroup file %q", string(contents), fileName)
    66  	}
    67  	return res, nil
    68  }
    69  
    70  // Gets a string value from the specified cgroup file
    71  func getCgroupParamString(cgroupPath, cgroupFile string) (string, error) {
    72  	contents, err := ioutil.ReadFile(filepath.Join(cgroupPath, cgroupFile))
    73  	if err != nil {
    74  		return "", err
    75  	}
    76  
    77  	return strings.TrimSpace(string(contents)), nil
    78  }