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 }