Skip to content

Commit

Permalink
validation: add cgroup devices validation
Browse files Browse the repository at this point in the history
Signed-off-by: Zhou Hao <[email protected]>
  • Loading branch information
Zhou Hao committed May 11, 2018
1 parent 1f9c0f1 commit 762800c
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 0 deletions.
46 changes: 46 additions & 0 deletions cgroups/cgroups_v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,52 @@ func (cg *CgroupV1) GetCPUData(pid int, cgPath string) (*rspec.LinuxCPU, error)
// GetDevicesData gets cgroup devices data
func (cg *CgroupV1) GetDevicesData(pid int, cgPath string) ([]rspec.LinuxDeviceCgroup, error) {
ld := []rspec.LinuxDeviceCgroup{}
fileName := strings.Join([]string{"devices", "list"}, ".")
filePath := filepath.Join(cg.MountPath, "devices", cgPath, fileName)
if !filepath.IsAbs(cgPath) {
subPath, err := GetSubsystemPath(pid, "devices")
if err != nil {
return nil, err
}
if !strings.Contains(subPath, cgPath) {
return nil, fmt.Errorf("cgroup subsystem %s is not mounted as expected", "devices")
}
filePath = filepath.Join(cg.MountPath, "devices", subPath, fileName)
}
contents, err := ioutil.ReadFile(filePath)
if err != nil {
return nil, err
}
parts := strings.Split(strings.TrimSpace(string(contents)), "\n")
for _, part := range parts {
elem := strings.Split(part, " ")
ele := strings.Split(elem[1], ":")
var major, minor int64
if ele[0] == "*" {
major = 0
} else {
major, err = strconv.ParseInt(ele[0], 10, 64)
if err != nil {
return nil, err
}
}
if ele[1] == "*" {
minor = 0
} else {
minor, err = strconv.ParseInt(ele[1], 10, 64)
if err != nil {
return nil, err
}
}

device := rspec.LinuxDeviceCgroup{}
device.Allow = true
device.Type = elem[0]
device.Major = &major
device.Minor = &minor
device.Access = elem[2]
ld = append(ld, device)
}

return ld, nil
}
Expand Down
22 changes: 22 additions & 0 deletions validation/linux_cgroups_devices.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package main

import (
"github.com/opencontainers/runtime-tools/cgroups"
"github.com/opencontainers/runtime-tools/validation/util"
)

func main() {
var major1, minor1, major2, minor2, major3, minor3 int64 = 10, 229, 8, 0, 10, 200
g, err := util.GetDefaultGenerator()
if err != nil {
util.Fatal(err)
}
g.SetLinuxCgroupsPath(cgroups.AbsCgroupPath)
g.AddLinuxResourcesDevice(true, "c", &major1, &minor1, "rwm")
g.AddLinuxResourcesDevice(false, "b", &major2, &minor2, "rw")
g.AddLinuxResourcesDevice(true, "a", &major3, &minor3, "r")
err = util.RuntimeOutsideValidate(g, util.ValidateLinuxResourcesDevices)
if err != nil {
util.Fatal(err)
}
}
22 changes: 22 additions & 0 deletions validation/linux_cgroups_relative_devices.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package main

import (
"github.com/opencontainers/runtime-tools/cgroups"
"github.com/opencontainers/runtime-tools/validation/util"
)

func main() {
var major1, minor1, major2, minor2, major3, minor3 int64 = 10, 229, 8, 0, 10, 200
g, err := util.GetDefaultGenerator()
if err != nil {
util.Fatal(err)
}
g.SetLinuxCgroupsPath(cgroups.RelCgroupPath)
g.AddLinuxResourcesDevice(true, "c", &major1, &minor1, "rwm")
g.AddLinuxResourcesDevice(false, "b", &major2, &minor2, "rw")
g.AddLinuxResourcesDevice(true, "a", &major3, &minor3, "r")
err = util.RuntimeOutsideValidate(g, util.ValidateLinuxResourcesDevices)
if err != nil {
util.Fatal(err)
}
}
47 changes: 47 additions & 0 deletions validation/util/linux_resources_devices.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package util

import (
"fmt"

"github.com/mndrix/tap-go"
rspec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/cgroups"
)

// ValidateLinuxResourcesDevices validates linux.resources.devices.
func ValidateLinuxResourcesDevices(config *rspec.Spec, state *rspec.State) error {
t := tap.New()
t.Header(0)

cg, err := cgroups.FindCgroup()
t.Ok((err == nil), "find devices")
if err != nil {
t.Diagnostic(err.Error())
t.AutoPlan()
return nil
}

lnd, err := cg.GetDevicesData(state.Pid, config.Linux.CgroupsPath)
t.Ok((err == nil), "get devices data")
if err != nil {
t.Diagnostic(err.Error())
t.AutoPlan()
return nil
}

for _, device := range config.Linux.Resources.Devices {
for _, lid := range lnd {
if lid.Allow == device.Allow {
t.Ok(lid.Allow == device.Allow && lid.Type == device.Type && *lid.Major == *device.Major &&
*lid.Minor == *device.Minor && lid.Access == device.Access,
fmt.Sprintf("devices %s %d:%d %s is set correctly",
device.Type, *device.Major, *device.Minor, device.Access))
t.Diagnosticf("expect: %s %d:%d %s, actual: %s %d:%d %s",
device.Type, *device.Major, *device.Minor, device.Access, lid.Type, *lid.Major, *lid.Minor, lid.Access)
}
}
}

t.AutoPlan()
return nil
}

0 comments on commit 762800c

Please sign in to comment.