...

Source file src/github.com/opencontainers/runc/libcontainer/cgroups/fs2/cpu.go

Documentation: github.com/opencontainers/runc/libcontainer/cgroups/fs2

     1  package fs2
     2  
     3  import (
     4  	"bufio"
     5  	"os"
     6  	"strconv"
     7  
     8  	"github.com/opencontainers/runc/libcontainer/cgroups"
     9  	"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
    10  	"github.com/opencontainers/runc/libcontainer/configs"
    11  )
    12  
    13  func isCpuSet(r *configs.Resources) bool {
    14  	return r.CpuWeight != 0 || r.CpuQuota != 0 || r.CpuPeriod != 0
    15  }
    16  
    17  func setCpu(dirPath string, r *configs.Resources) error {
    18  	if !isCpuSet(r) {
    19  		return nil
    20  	}
    21  
    22  	// NOTE: .CpuShares is not used here. Conversion is the caller's responsibility.
    23  	if r.CpuWeight != 0 {
    24  		if err := cgroups.WriteFile(dirPath, "cpu.weight", strconv.FormatUint(r.CpuWeight, 10)); err != nil {
    25  			return err
    26  		}
    27  	}
    28  
    29  	if r.CpuQuota != 0 || r.CpuPeriod != 0 {
    30  		str := "max"
    31  		if r.CpuQuota > 0 {
    32  			str = strconv.FormatInt(r.CpuQuota, 10)
    33  		}
    34  		period := r.CpuPeriod
    35  		if period == 0 {
    36  			// This default value is documented in
    37  			// https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html
    38  			period = 100000
    39  		}
    40  		str += " " + strconv.FormatUint(period, 10)
    41  		if err := cgroups.WriteFile(dirPath, "cpu.max", str); err != nil {
    42  			return err
    43  		}
    44  	}
    45  
    46  	return nil
    47  }
    48  
    49  func statCpu(dirPath string, stats *cgroups.Stats) error {
    50  	const file = "cpu.stat"
    51  	f, err := cgroups.OpenFile(dirPath, file, os.O_RDONLY)
    52  	if err != nil {
    53  		return err
    54  	}
    55  	defer f.Close()
    56  
    57  	sc := bufio.NewScanner(f)
    58  	for sc.Scan() {
    59  		t, v, err := fscommon.ParseKeyValue(sc.Text())
    60  		if err != nil {
    61  			return &parseError{Path: dirPath, File: file, Err: err}
    62  		}
    63  		switch t {
    64  		case "usage_usec":
    65  			stats.CpuStats.CpuUsage.TotalUsage = v * 1000
    66  
    67  		case "user_usec":
    68  			stats.CpuStats.CpuUsage.UsageInUsermode = v * 1000
    69  
    70  		case "system_usec":
    71  			stats.CpuStats.CpuUsage.UsageInKernelmode = v * 1000
    72  
    73  		case "nr_periods":
    74  			stats.CpuStats.ThrottlingData.Periods = v
    75  
    76  		case "nr_throttled":
    77  			stats.CpuStats.ThrottlingData.ThrottledPeriods = v
    78  
    79  		case "throttled_usec":
    80  			stats.CpuStats.ThrottlingData.ThrottledTime = v * 1000
    81  		}
    82  	}
    83  	if err := sc.Err(); err != nil {
    84  		return &parseError{Path: dirPath, File: file, Err: err}
    85  	}
    86  	return nil
    87  }
    88  

View as plain text