Skip to content

Commit 1aebc09

Browse files
author
Ma Shimiao
committed
update to support relative cgrouppath test
Signed-off-by: Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>
1 parent 6351044 commit 1aebc09

10 files changed

Lines changed: 161 additions & 42 deletions

cgroups/cgroups.go

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,30 @@ package cgroups
33
import (
44
"bufio"
55
"fmt"
6+
"io/ioutil"
67
"os"
78
"path/filepath"
89
"strings"
910

1011
rspec "github.com/opencontainers/runtime-spec/specs-go"
1112
)
1213

14+
var (
15+
// AbsCgroupPath is absolute path for container's cgroup mount
16+
AbsCgroupPath = "/cgrouptest"
17+
// RelCgroupPath is relative path for container's cgroup mount
18+
RelCgroupPath = "testdir/cgrouptest/container"
19+
)
20+
1321
// Cgroup represents interfaces for cgroup validation
1422
type Cgroup interface {
15-
GetBlockIOData(cgPath string) (*rspec.LinuxBlockIO, error)
16-
GetCPUData(cgPath string) (*rspec.LinuxCPU, error)
17-
GetDevicesData(cgPath string) ([]rspec.LinuxDeviceCgroup, error)
18-
GetHugepageLimitData(cgPath string) ([]rspec.LinuxHugepageLimit, error)
19-
GetMemoryData(cgPath string) (*rspec.LinuxMemory, error)
20-
GetNetworkData(cgPath string) (*rspec.LinuxNetwork, error)
21-
GetPidsData(cgPath string) (*rspec.LinuxPids, error)
23+
GetBlockIOData(pid int, cgPath string) (*rspec.LinuxBlockIO, error)
24+
GetCPUData(pid int, cgPath string) (*rspec.LinuxCPU, error)
25+
GetDevicesData(pid int, cgPath string) ([]rspec.LinuxDeviceCgroup, error)
26+
GetHugepageLimitData(pid int, cgPath string) ([]rspec.LinuxHugepageLimit, error)
27+
GetMemoryData(pid int, cgPath string) (*rspec.LinuxMemory, error)
28+
GetNetworkData(pid int, cgPath string) (*rspec.LinuxNetwork, error)
29+
GetPidsData(pid int, cgPath string) (*rspec.LinuxPids, error)
2230
}
2331

2432
// FindCgroup gets cgroup root mountpoint
@@ -70,3 +78,27 @@ func FindCgroup() (Cgroup, error) {
7078
}
7179
return nil, fmt.Errorf("cgroup is not found")
7280
}
81+
82+
// GetSubsystemPath gets path of subsystem
83+
func GetSubsystemPath(pid int, subsystem string) (string, error) {
84+
contents, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cgroup", pid))
85+
if err != nil {
86+
return "", err
87+
}
88+
89+
parts := strings.Split(strings.TrimSpace(string(contents)), "\n")
90+
for _, part := range parts {
91+
elem := strings.SplitN(part, ":", 3)
92+
if len(elem) < 3 {
93+
continue
94+
}
95+
subelems := strings.Split(elem[1], ",")
96+
for _, subelem := range subelems {
97+
if subelem == subsystem {
98+
return elem[2], nil
99+
}
100+
}
101+
}
102+
103+
return "", fmt.Errorf("subsystem %s not found", subsystem)
104+
}

cgroups/cgroups_v1.go

Lines changed: 87 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,22 @@ func getDeviceID(id string) (int64, int64, error) {
3030
}
3131

3232
// GetBlockIOData gets cgroup blockio data
33-
func (cg *CgroupV1) GetBlockIOData(cgPath string) (*rspec.LinuxBlockIO, error) {
33+
func (cg *CgroupV1) GetBlockIOData(pid int, cgPath string) (*rspec.LinuxBlockIO, error) {
3434
lb := &rspec.LinuxBlockIO{}
3535
names := []string{"weight", "leaf_weight", "weight_device", "leaf_weight_device", "throttle.read_bps_device", "throttle.write_bps_device", "throttle.read_iops_device", "throttle.write_iops_device"}
3636
for i, name := range names {
3737
fileName := strings.Join([]string{"blkio", name}, ".")
3838
filePath := filepath.Join(cg.MountPath, "blkio", cgPath, fileName)
39+
if !filepath.IsAbs(cgPath) {
40+
subPath, err := GetSubsystemPath(pid, "blkio")
41+
if err != nil {
42+
return nil, err
43+
}
44+
if !strings.Contains(subPath, RelCgroupPath) {
45+
return nil, fmt.Errorf("cgroup subsystem %s is not mounted as expected", "blkio")
46+
}
47+
filePath = filepath.Join(cg.MountPath, "blkio", subPath, fileName)
48+
}
3949
contents, err := ioutil.ReadFile(filePath)
4050
if err != nil {
4151
return nil, err
@@ -182,12 +192,22 @@ func (cg *CgroupV1) GetBlockIOData(cgPath string) (*rspec.LinuxBlockIO, error) {
182192
}
183193

184194
// GetCPUData gets cgroup cpus data
185-
func (cg *CgroupV1) GetCPUData(cgPath string) (*rspec.LinuxCPU, error) {
195+
func (cg *CgroupV1) GetCPUData(pid int, cgPath string) (*rspec.LinuxCPU, error) {
186196
lc := &rspec.LinuxCPU{}
187197
names := []string{"shares", "cfs_quota_us", "cfs_period_us"}
188198
for i, name := range names {
189199
fileName := strings.Join([]string{"cpu", name}, ".")
190200
filePath := filepath.Join(cg.MountPath, "cpu", cgPath, fileName)
201+
if !filepath.IsAbs(cgPath) {
202+
subPath, err := GetSubsystemPath(pid, "cpu")
203+
if err != nil {
204+
return nil, err
205+
}
206+
if !strings.Contains(subPath, RelCgroupPath) {
207+
return nil, fmt.Errorf("cgroup subsystem %s is not mounted as expected", "cpu")
208+
}
209+
filePath = filepath.Join(cg.MountPath, "cpu", subPath, fileName)
210+
}
191211
contents, err := ioutil.ReadFile(filePath)
192212
if err != nil {
193213
return nil, err
@@ -241,6 +261,16 @@ func (cg *CgroupV1) GetCPUData(cgPath string) (*rspec.LinuxCPU, error) {
241261
for i, name := range names {
242262
fileName := strings.Join([]string{"cpuset", name}, ".")
243263
filePath := filepath.Join(cg.MountPath, "cpuset", cgPath, fileName)
264+
if !filepath.IsAbs(cgPath) {
265+
subPath, err := GetSubsystemPath(pid, "cpuset")
266+
if err != nil {
267+
return nil, err
268+
}
269+
if !strings.Contains(subPath, RelCgroupPath) {
270+
return nil, fmt.Errorf("cgroup subsystem %s is not mounted as expected", "cpuset")
271+
}
272+
filePath = filepath.Join(cg.MountPath, "cpuset", subPath, fileName)
273+
}
244274
contents, err := ioutil.ReadFile(filePath)
245275
if err != nil {
246276
return nil, err
@@ -257,7 +287,7 @@ func (cg *CgroupV1) GetCPUData(cgPath string) (*rspec.LinuxCPU, error) {
257287
}
258288

259289
// GetDevicesData gets cgroup devices data
260-
func (cg *CgroupV1) GetDevicesData(cgPath string) ([]rspec.LinuxDeviceCgroup, error) {
290+
func (cg *CgroupV1) GetDevicesData(pid int, cgPath string) ([]rspec.LinuxDeviceCgroup, error) {
261291
ld := []rspec.LinuxDeviceCgroup{}
262292

263293
return ld, nil
@@ -318,7 +348,7 @@ func getHugePageSize() ([]string, error) {
318348
}
319349

320350
// GetHugepageLimitData gets cgroup hugetlb data
321-
func (cg *CgroupV1) GetHugepageLimitData(cgPath string) ([]rspec.LinuxHugepageLimit, error) {
351+
func (cg *CgroupV1) GetHugepageLimitData(pid int, cgPath string) ([]rspec.LinuxHugepageLimit, error) {
322352
lh := []rspec.LinuxHugepageLimit{}
323353
pageSizes, err := getHugePageSize()
324354
if err != nil {
@@ -327,6 +357,16 @@ func (cg *CgroupV1) GetHugepageLimitData(cgPath string) ([]rspec.LinuxHugepageLi
327357
for _, pageSize := range pageSizes {
328358
maxUsage := strings.Join([]string{"hugetlb", pageSize, "limit_in_bytes"}, ".")
329359
filePath := filepath.Join(cg.MountPath, "hugetlb", cgPath, maxUsage)
360+
if !filepath.IsAbs(cgPath) {
361+
subPath, err := GetSubsystemPath(pid, "hugetlb")
362+
if err != nil {
363+
return lh, err
364+
}
365+
if !strings.Contains(subPath, RelCgroupPath) {
366+
return nil, fmt.Errorf("cgroup subsystem %s is not mounted as expected", "hugetlb")
367+
}
368+
filePath = filepath.Join(cg.MountPath, "hugetlb", subPath, maxUsage)
369+
}
330370
contents, err := ioutil.ReadFile(filePath)
331371
if err != nil {
332372
return lh, err
@@ -345,12 +385,22 @@ func (cg *CgroupV1) GetHugepageLimitData(cgPath string) ([]rspec.LinuxHugepageLi
345385
}
346386

347387
// GetMemoryData gets cgroup memory data
348-
func (cg *CgroupV1) GetMemoryData(cgPath string) (*rspec.LinuxMemory, error) {
388+
func (cg *CgroupV1) GetMemoryData(pid int, cgPath string) (*rspec.LinuxMemory, error) {
349389
lm := &rspec.LinuxMemory{}
350390
names := []string{"limit_in_bytes", "soft_limit_in_bytes", "memsw.limit_in_bytes", "kmem.limit_in_bytes", "kmem.tcp.limit_in_bytes", "swappiness", "oom_control"}
351391
for i, name := range names {
352392
fileName := strings.Join([]string{"memory", name}, ".")
353393
filePath := filepath.Join(cg.MountPath, "memory", cgPath, fileName)
394+
if !filepath.IsAbs(cgPath) {
395+
subPath, err := GetSubsystemPath(pid, "memory")
396+
if err != nil {
397+
return nil, err
398+
}
399+
if !strings.Contains(subPath, RelCgroupPath) {
400+
return nil, fmt.Errorf("cgroup subsystem %s is not mounted as expected", "memory")
401+
}
402+
filePath = filepath.Join(cg.MountPath, "memory", subPath, fileName)
403+
}
354404
contents, err := ioutil.ReadFile(filePath)
355405
if err != nil {
356406
return nil, err
@@ -417,10 +467,20 @@ func (cg *CgroupV1) GetMemoryData(cgPath string) (*rspec.LinuxMemory, error) {
417467
}
418468

419469
// GetNetworkData gets cgroup network data
420-
func (cg *CgroupV1) GetNetworkData(cgPath string) (*rspec.LinuxNetwork, error) {
470+
func (cg *CgroupV1) GetNetworkData(pid int, cgPath string) (*rspec.LinuxNetwork, error) {
421471
ln := &rspec.LinuxNetwork{}
422472
fileName := strings.Join([]string{"net_cls", "classid"}, ".")
423473
filePath := filepath.Join(cg.MountPath, "net_cls", cgPath, fileName)
474+
if !filepath.IsAbs(cgPath) {
475+
subPath, err := GetSubsystemPath(pid, "net_cls")
476+
if err != nil {
477+
return nil, err
478+
}
479+
if !strings.Contains(subPath, RelCgroupPath) {
480+
return nil, fmt.Errorf("cgroup subsystem %s is not mounted as expected", "net_cls")
481+
}
482+
filePath = filepath.Join(cg.MountPath, "net_cls", subPath, fileName)
483+
}
424484
contents, err := ioutil.ReadFile(filePath)
425485
if err != nil {
426486
return nil, err
@@ -434,6 +494,16 @@ func (cg *CgroupV1) GetNetworkData(cgPath string) (*rspec.LinuxNetwork, error) {
434494

435495
fileName = strings.Join([]string{"net_prio", "ifpriomap"}, ".")
436496
filePath = filepath.Join(cg.MountPath, "net_prio", cgPath, fileName)
497+
if !filepath.IsAbs(cgPath) {
498+
subPath, err := GetSubsystemPath(pid, "net_prio")
499+
if err != nil {
500+
return nil, err
501+
}
502+
if !strings.Contains(subPath, RelCgroupPath) {
503+
return nil, fmt.Errorf("cgroup subsystem %s is not mounted as expected", "net_prio")
504+
}
505+
filePath = filepath.Join(cg.MountPath, "net_prio", subPath, fileName)
506+
}
437507
contents, err = ioutil.ReadFile(filePath)
438508
if err != nil {
439509
return nil, err
@@ -455,10 +525,20 @@ func (cg *CgroupV1) GetNetworkData(cgPath string) (*rspec.LinuxNetwork, error) {
455525
}
456526

457527
// GetPidsData gets cgroup pids data
458-
func (cg *CgroupV1) GetPidsData(cgPath string) (*rspec.LinuxPids, error) {
528+
func (cg *CgroupV1) GetPidsData(pid int, cgPath string) (*rspec.LinuxPids, error) {
459529
lp := &rspec.LinuxPids{}
460530
fileName := strings.Join([]string{"pids", "max"}, ".")
461531
filePath := filepath.Join(cg.MountPath, "pids", cgPath, fileName)
532+
if !filepath.IsAbs(cgPath) {
533+
subPath, err := GetSubsystemPath(pid, "pids")
534+
if err != nil {
535+
return nil, err
536+
}
537+
if !strings.Contains(subPath, RelCgroupPath) {
538+
return nil, fmt.Errorf("cgroup subsystem %s is not mounted as expected", "pids")
539+
}
540+
filePath = filepath.Join(cg.MountPath, "pids", subPath, fileName)
541+
}
462542
contents, err := ioutil.ReadFile(filePath)
463543
if err != nil {
464544
return nil, err

cgroups/cgroups_v2.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,36 +12,36 @@ type CgroupV2 struct {
1212
}
1313

1414
// GetBlockIOData gets cgroup blockio data
15-
func GetBlockIOData(cgPath string) (*rspec.LinuxBlockIO, error) {
15+
func GetBlockIOData(pid int, cgPath string) (*rspec.LinuxBlockIO, error) {
1616
return nil, fmt.Errorf("unimplemented yet")
1717
}
1818

1919
// GetCPUData gets cgroup cpus data
20-
func GetCPUData(cgPath string) (*rspec.LinuxCPU, error) {
20+
func GetCPUData(pid int, cgPath string) (*rspec.LinuxCPU, error) {
2121
return nil, fmt.Errorf("unimplemented yet")
2222
}
2323

2424
// GetDevicesData gets cgroup devices data
25-
func GetDevicesData(cgPath string) ([]rspec.LinuxDeviceCgroup, error) {
25+
func GetDevicesData(pid int, cgPath string) ([]rspec.LinuxDeviceCgroup, error) {
2626
return nil, fmt.Errorf("unimplemented yet")
2727
}
2828

2929
// GetHugepageLimitData gets cgroup hugetlb data
30-
func GetHugepageLimitData(cgPath string) ([]rspec.LinuxHugepageLimit, error) {
30+
func GetHugepageLimitData(pid int, cgPath string) ([]rspec.LinuxHugepageLimit, error) {
3131
return nil, fmt.Errorf("unimplemented yet")
3232
}
3333

3434
// GetMemoryData gets cgroup memory data
35-
func (cg *CgroupV2) GetMemoryData(cgPath string) (*rspec.LinuxMemory, error) {
35+
func (cg *CgroupV2) GetMemoryData(pid int, cgPath string) (*rspec.LinuxMemory, error) {
3636
return nil, fmt.Errorf("unimplemented yet")
3737
}
3838

3939
// GetNetworkData gets cgroup network data
40-
func GetNetworkData(cgPath string) (*rspec.LinuxNetwork, error) {
40+
func GetNetworkData(pid int, cgPath string) (*rspec.LinuxNetwork, error) {
4141
return nil, fmt.Errorf("unimplemented yet")
4242
}
4343

44-
// GetPidsData gets cgroup pids data
45-
func GetPidsData(cgPath string) (*rspec.LinuxPids, error) {
44+
// GetPidsData gets cgroup pid ints data
45+
func GetPidsData(pid int, cgPath string) (*rspec.LinuxPids, error) {
4646
return nil, fmt.Errorf("unimplemented yet")
4747
}

validation/linux_cgroups_blkio.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ func main() {
1313
var major, minor int64 = 8, 0
1414
var rate uint64 = 102400
1515
g := util.GetDefaultGenerator()
16-
g.SetLinuxCgroupsPath("/test")
16+
g.SetLinuxCgroupsPath(cgroups.AbsCgroupPath)
1717
g.SetLinuxResourcesBlockIOWeight(weight)
1818
g.SetLinuxResourcesBlockIOLeafWeight(leafWeight)
1919
g.AddLinuxResourcesBlockIOWeightDevice(major, minor, weight)
@@ -22,12 +22,12 @@ func main() {
2222
g.AddLinuxResourcesBlockIOThrottleWriteBpsDevice(major, minor, rate)
2323
g.AddLinuxResourcesBlockIOThrottleReadIOPSDevice(major, minor, rate)
2424
g.AddLinuxResourcesBlockIOThrottleWriteIOPSDevice(major, minor, rate)
25-
err := util.RuntimeOutsideValidate(g, func(path string) error {
25+
err := util.RuntimeOutsideValidate(g, cgroups.AbsCgroupPath, func(pid int, path string) error {
2626
cg, err := cgroups.FindCgroup()
2727
if err != nil {
2828
return err
2929
}
30-
lbd, err := cg.GetBlockIOData(path)
30+
lbd, err := cg.GetBlockIOData(pid, path)
3131
if err != nil {
3232
return err
3333
}

validation/linux_cgroups_cpus.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,18 @@ func main() {
1313
var quota int64 = 50000
1414
var cpus, mems string = "0-1", "0"
1515
g := util.GetDefaultGenerator()
16-
g.SetLinuxCgroupsPath("/test")
16+
g.SetLinuxCgroupsPath(cgroups.AbsCgroupPath)
1717
g.SetLinuxResourcesCPUShares(shares)
1818
g.SetLinuxResourcesCPUQuota(quota)
1919
g.SetLinuxResourcesCPUPeriod(period)
2020
g.SetLinuxResourcesCPUCpus(cpus)
2121
g.SetLinuxResourcesCPUMems(mems)
22-
err := util.RuntimeOutsideValidate(g, func(path string) error {
22+
err := util.RuntimeOutsideValidate(g, cgroups.AbsCgroupPath, func(pid int, path string) error {
2323
cg, err := cgroups.FindCgroup()
2424
if err != nil {
2525
return err
2626
}
27-
lcd, err := cg.GetCPUData(path)
27+
lcd, err := cg.GetCPUData(pid, path)
2828
if err != nil {
2929
return err
3030
}

validation/linux_cgroups_hugetlb.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ func main() {
1111
page := "1GB"
1212
var limit uint64 = 56892210544640
1313
g := util.GetDefaultGenerator()
14-
g.SetLinuxCgroupsPath("/test")
14+
g.SetLinuxCgroupsPath(cgroups.AbsCgroupPath)
1515
g.AddLinuxResourcesHugepageLimit(page, limit)
16-
err := util.RuntimeOutsideValidate(g, func(path string) error {
16+
err := util.RuntimeOutsideValidate(g, cgroups.AbsCgroupPath, func(pid int, path string) error {
1717
cg, err := cgroups.FindCgroup()
1818
if err != nil {
1919
return err
2020
}
21-
lhd, err := cg.GetHugepageLimitData(path)
21+
lhd, err := cg.GetHugepageLimitData(pid, path)
2222
if err != nil {
2323
return err
2424
}

validation/linux_cgroups_memory.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,20 @@ func main() {
1111
var limit int64 = 50593792
1212
var swappiness uint64 = 50
1313
g := util.GetDefaultGenerator()
14-
g.SetLinuxCgroupsPath("/test")
14+
g.SetLinuxCgroupsPath(cgroups.AbsCgroupPath)
1515
g.SetLinuxResourcesMemoryLimit(limit)
1616
g.SetLinuxResourcesMemoryReservation(limit)
1717
g.SetLinuxResourcesMemorySwap(limit)
1818
g.SetLinuxResourcesMemoryKernel(limit)
1919
g.SetLinuxResourcesMemoryKernelTCP(limit)
2020
g.SetLinuxResourcesMemorySwappiness(swappiness)
2121
g.SetLinuxResourcesMemoryDisableOOMKiller(true)
22-
err := util.RuntimeOutsideValidate(g, func(path string) error {
22+
err := util.RuntimeOutsideValidate(g, cgroups.AbsCgroupPath, func(pid int, path string) error {
2323
cg, err := cgroups.FindCgroup()
2424
if err != nil {
2525
return err
2626
}
27-
lm, err := cg.GetMemoryData(path)
27+
lm, err := cg.GetMemoryData(pid, path)
2828
if err != nil {
2929
return err
3030
}

0 commit comments

Comments
 (0)