github.com/opencontainers/runtime-tools@v0.9.0/validation/util/linux_resources_cpus.go (about)

     1  package util
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"path/filepath"
     7  	"runtime"
     8  	"strconv"
     9  	"strings"
    10  
    11  	"github.com/mndrix/tap-go"
    12  	rspec "github.com/opencontainers/runtime-spec/specs-go"
    13  	"github.com/opencontainers/runtime-tools/cgroups"
    14  )
    15  
    16  const (
    17  	// CPUCgroupPrefix is default path prefix where CPU cgroups are created
    18  	CPUCgroupPrefix string = "/sys/fs/cgroup/cpu,cpuacct"
    19  )
    20  
    21  // ValidateLinuxResourcesCPU validates if Linux.Resources.CPU is set to
    22  // correct values, the same as given values in the config.
    23  func ValidateLinuxResourcesCPU(config *rspec.Spec, t *tap.T, state *rspec.State) error {
    24  	cg, err := cgroups.FindCgroup()
    25  	t.Ok((err == nil), "find cpu cgroup")
    26  	if err != nil {
    27  		t.Diagnostic(err.Error())
    28  		return nil
    29  	}
    30  
    31  	lcd, err := cg.GetCPUData(state.Pid, config.Linux.CgroupsPath)
    32  	t.Ok((err == nil), "get cpu cgroup data")
    33  	if err != nil {
    34  		t.Diagnostic(err.Error())
    35  		return nil
    36  	}
    37  
    38  	if lcd.Shares == nil || config.Linux.Resources.CPU.Shares == nil {
    39  		t.Diagnostic(fmt.Sprintf("unable to get cpu shares, lcd.Shares == %v, config.Linux.Resources.CPU.Shares == %v", lcd.Shares, config.Linux.Resources.CPU.Shares))
    40  		return nil
    41  	}
    42  	t.Ok(*lcd.Shares == *config.Linux.Resources.CPU.Shares, "cpu shares is set correctly")
    43  	t.Diagnosticf("expect: %d, actual: %d", *config.Linux.Resources.CPU.Shares, *lcd.Shares)
    44  
    45  	if lcd.Period == nil || config.Linux.Resources.CPU.Period == nil {
    46  		t.Diagnostic(fmt.Sprintf("unable to get cpu period, lcd.Period == %v, config.Linux.Resources.CPU.Period == %v", lcd.Period, config.Linux.Resources.CPU.Period))
    47  		return nil
    48  	}
    49  	t.Ok(*lcd.Period == *config.Linux.Resources.CPU.Period, "cpu period is set correctly")
    50  	t.Diagnosticf("expect: %d, actual: %d", *config.Linux.Resources.CPU.Period, *lcd.Period)
    51  
    52  	if lcd.Quota == nil || config.Linux.Resources.CPU.Quota == nil {
    53  		t.Diagnostic(fmt.Sprintf("unable to get cpu quota, lcd.Quota == %v, config.Linux.Resources.CPU.Quota == %v", lcd.Quota, config.Linux.Resources.CPU.Quota))
    54  		return nil
    55  	}
    56  	t.Ok(*lcd.Quota == *config.Linux.Resources.CPU.Quota, "cpu quota is set correctly")
    57  	t.Diagnosticf("expect: %d, actual: %d", *config.Linux.Resources.CPU.Quota, *lcd.Quota)
    58  
    59  	t.Ok(lcd.Cpus == config.Linux.Resources.CPU.Cpus, "cpu cpus is set correctly")
    60  	t.Diagnosticf("expect: %s, actual: %s", config.Linux.Resources.CPU.Cpus, lcd.Cpus)
    61  
    62  	t.Ok(lcd.Mems == config.Linux.Resources.CPU.Mems, "cpu mems is set correctly")
    63  	t.Diagnosticf("expect: %s, actual: %s", config.Linux.Resources.CPU.Mems, lcd.Mems)
    64  
    65  	return nil
    66  }
    67  
    68  // ValidateLinuxResourcesCPUEmpty validates Linux.Resources.CPU is set to
    69  // correct values, when each value are set to the default ones.
    70  func ValidateLinuxResourcesCPUEmpty(config *rspec.Spec, t *tap.T, state *rspec.State) error {
    71  	outShares, err := ioutil.ReadFile(filepath.Join(CPUCgroupPrefix, "cpu.shares"))
    72  	if err != nil {
    73  		return nil
    74  	}
    75  	sh, _ := strconv.Atoi(strings.TrimSpace(string(outShares)))
    76  	defaultShares := uint64(sh)
    77  
    78  	outPeriod, err := ioutil.ReadFile(filepath.Join(CPUCgroupPrefix, "cpu.cfs_period_us"))
    79  	if err != nil {
    80  		return nil
    81  	}
    82  	pe, _ := strconv.Atoi(strings.TrimSpace(string(outPeriod)))
    83  	defaultPeriod := uint64(pe)
    84  
    85  	outQuota, err := ioutil.ReadFile(filepath.Join(CPUCgroupPrefix, "cpu.cfs_quota_us"))
    86  	if err != nil {
    87  		return nil
    88  	}
    89  	qu, _ := strconv.Atoi(strings.TrimSpace(string(outQuota)))
    90  	defaultQuota := int64(qu)
    91  
    92  	defaultCpus := fmt.Sprintf("0-%d", runtime.NumCPU()-1)
    93  	defaultMems := "0"
    94  
    95  	cg, err := cgroups.FindCgroup()
    96  	t.Ok((err == nil), "find cpu cgroup")
    97  	if err != nil {
    98  		t.Diagnostic(err.Error())
    99  		return nil
   100  	}
   101  
   102  	lcd, err := cg.GetCPUData(state.Pid, config.Linux.CgroupsPath)
   103  	t.Ok((err == nil), "get cpu cgroup data")
   104  	if err != nil {
   105  		t.Diagnostic(err.Error())
   106  		return nil
   107  	}
   108  
   109  	if lcd.Shares == nil {
   110  		t.Diagnostic(fmt.Sprintf("unable to get cpu shares, lcd.Shares == %v", lcd.Shares))
   111  		return nil
   112  	}
   113  	t.Ok(*lcd.Shares == defaultShares, "cpu shares is set correctly")
   114  	t.Diagnosticf("expect: %d, actual: %d", defaultShares, *lcd.Shares)
   115  
   116  	if lcd.Period == nil {
   117  		t.Diagnostic(fmt.Sprintf("unable to get cpu period, lcd.Period == %v", lcd.Period))
   118  		return nil
   119  	}
   120  	t.Ok(*lcd.Period == defaultPeriod, "cpu period is set correctly")
   121  	t.Diagnosticf("expect: %d, actual: %d", defaultPeriod, *lcd.Period)
   122  
   123  	if lcd.Quota == nil {
   124  		t.Diagnostic(fmt.Sprintf("unable to get cpu quota, lcd.Quota == %v", lcd.Quota))
   125  		return nil
   126  	}
   127  	t.Ok(*lcd.Quota == defaultQuota, "cpu quota is set correctly")
   128  	t.Diagnosticf("expect: %d, actual: %d", defaultQuota, *lcd.Quota)
   129  
   130  	t.Ok(lcd.Cpus == defaultCpus, "cpu cpus is set correctly")
   131  	t.Diagnosticf("expect: %s, actual: %s", defaultCpus, lcd.Cpus)
   132  
   133  	t.Ok(lcd.Mems == defaultMems, "cpu mems is set correctly")
   134  	t.Diagnosticf("expect: %s, actual: %s", defaultMems, lcd.Mems)
   135  
   136  	return nil
   137  }