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 <zhouhao@cn.fujitsu.com>
  • Loading branch information
Zhou Hao committed May 21, 2018
1 parent 1f9c0f1 commit 1794938
Show file tree
Hide file tree
Showing 4 changed files with 143 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, 20, 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(true, "b", &major2, &minor2, "rw")
g.AddLinuxResourcesDevice(true, "b", &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, 20, 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(true, "b", &major2, &minor2, "rw")
g.AddLinuxResourcesDevice(true, "b", &major3, &minor3, "r")
err = util.RuntimeOutsideValidate(g, util.ValidateLinuxResourcesDevices)
if err != nil {
util.Fatal(err)
}
}
53 changes: 53 additions & 0 deletions validation/util/linux_resources_devices.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package util

import (
"fmt"

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

// 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 i, device := range config.Linux.Resources.Devices {
if device.Allow == true {
found := false
if lnd[i-1].Type == device.Type && *lnd[i-1].Major == *device.Major && *lnd[i-1].Minor == *device.Minor && lnd[i-1].Access == device.Access {
found = true
}
t.Ok(found, 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, lnd[i-1].Type, *lnd[i-1].Major, *lnd[i-1].Minor, lnd[i-1].Access)
if !found {
err := specerror.NewError(specerror.DevicesApplyInOrder, fmt.Errorf("The runtime MUST apply entries in the listed order"), rspec.Version)
t.Diagnostic(err.Error())
t.AutoPlan()
return nil
}
}
}

t.AutoPlan()
return nil
}

0 comments on commit 1794938

Please sign in to comment.