Skip to content

Commit

Permalink
Merge pull request containers#10895 from rhatdan/devices
Browse files Browse the repository at this point in the history
Support DeviceCgroupRules to actually get added.
  • Loading branch information
openshift-merge-robot authored Jul 24, 2021
2 parents d956500 + 3e79296 commit ec5c7c1
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 0 deletions.
63 changes: 63 additions & 0 deletions cmd/podman/common/specgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,14 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
s.Devices = append(s.Devices, specs.LinuxDevice{Path: dev})
}

for _, rule := range c.DeviceCGroupRule {
dev, err := parseLinuxResourcesDeviceAccess(rule)
if err != nil {
return err
}
s.DeviceCGroupRule = append(s.DeviceCGroupRule, dev)
}

s.Init = c.Init
s.InitPath = c.InitPath
s.Stdin = c.Interactive
Expand Down Expand Up @@ -885,3 +893,58 @@ func parseSecrets(secrets []string) ([]specgen.Secret, map[string]string, error)
}
return mount, envs, nil
}

var cgroupDeviceType = map[string]bool{
"a": true, // all
"b": true, // block device
"c": true, // character device
}

var cgroupDeviceAccess = map[string]bool{
"r": true, //read
"w": true, //write
"m": true, //mknod
}

// parseLinuxResourcesDeviceAccess parses the raw string passed with the --device-access-add flag
func parseLinuxResourcesDeviceAccess(device string) (specs.LinuxDeviceCgroup, error) {
var devType, access string
var major, minor *int64

value := strings.Split(device, " ")
if len(value) != 3 {
return specs.LinuxDeviceCgroup{}, fmt.Errorf("invalid device cgroup rule requires type, major:Minor, and access rules: %q", device)
}

devType = value[0]
if !cgroupDeviceType[devType] {
return specs.LinuxDeviceCgroup{}, fmt.Errorf("invalid device type in device-access-add: %s", devType)
}

number := strings.SplitN(value[1], ":", 2)
i, err := strconv.ParseInt(number[0], 10, 64)
if err != nil {
return specs.LinuxDeviceCgroup{}, err
}
major = &i
if len(number) == 2 && number[1] != "*" {
i, err := strconv.ParseInt(number[1], 10, 64)
if err != nil {
return specs.LinuxDeviceCgroup{}, err
}
minor = &i
}
access = value[2]
for _, c := range strings.Split(access, "") {
if !cgroupDeviceAccess[c] {
return specs.LinuxDeviceCgroup{}, fmt.Errorf("invalid device access in device-access-add: %s", c)
}
}
return specs.LinuxDeviceCgroup{
Allow: true,
Type: devType,
Major: major,
Minor: minor,
Access: access,
}, nil
}
4 changes: 4 additions & 0 deletions pkg/specgen/generate/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,10 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt
}
}

for _, dev := range s.DeviceCGroupRule {
g.AddLinuxResourcesDevice(true, dev.Type, dev.Major, dev.Minor, dev.Access)
}

BlockAccessToKernelFilesystems(s.Privileged, s.PidNS.IsHost(), s.Mask, s.Unmask, &g)

for name, val := range s.Env {
Expand Down
3 changes: 3 additions & 0 deletions pkg/specgen/specgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ type ContainerStorageConfig struct {
// Devices are devices that will be added to the container.
// Optional.
Devices []spec.LinuxDevice `json:"devices,omitempty"`
// DeviceCGroupRule are device cgroup rules that allow containers
// to use additional types of devices.
DeviceCGroupRule []spec.LinuxDeviceCgroup `json:"device_cgroup_rule,omitempty"`
// IpcNS is the container's IPC namespace.
// Default is private.
// Conflicts with ShmSize if not set to private.
Expand Down
17 changes: 17 additions & 0 deletions test/system/030-run.bats
Original file line number Diff line number Diff line change
Expand Up @@ -706,4 +706,21 @@ EOF
run_podman rmi nomtab
}

@test "podman run --device-cgroup-rule tests" {
skip_if_rootless "cannot add devices in rootless mode"

run_podman run --device-cgroup-rule="b 7:* rmw" --rm $IMAGE
run_podman run --device-cgroup-rule="c 7:* rmw" --rm $IMAGE
run_podman run --device-cgroup-rule="a 7:1 rmw" --rm $IMAGE
run_podman run --device-cgroup-rule="a 7 rmw" --rm $IMAGE
run_podman 125 run --device-cgroup-rule="b 7:* rmX" --rm $IMAGE
is "$output" "Error: invalid device access in device-access-add: X"
run_podman 125 run --device-cgroup-rule="b 7:2" --rm $IMAGE
is "$output" 'Error: invalid device cgroup rule requires type, major:Minor, and access rules: "b 7:2"'
run_podman 125 run --device-cgroup-rule="x 7:* rmw" --rm $IMAGE
is "$output" "Error: invalid device type in device-access-add:"
run_podman 125 run --device-cgroup-rule="a a:* rmw" --rm $IMAGE
is "$output" "Error: strconv.ParseInt: parsing \"a\": invalid syntax"
}

# vim: filetype=sh

0 comments on commit ec5c7c1

Please sign in to comment.