summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pkg/spec/config_linux.go41
-rw-r--r--pkg/spec/spec.go6
-rw-r--r--test/e2e/run_device_test.go9
3 files changed, 50 insertions, 6 deletions
diff --git a/pkg/spec/config_linux.go b/pkg/spec/config_linux.go
index 9f6a4a058..a84e9a72f 100644
--- a/pkg/spec/config_linux.go
+++ b/pkg/spec/config_linux.go
@@ -8,6 +8,7 @@ import (
"path/filepath"
"strings"
+ "github.com/containers/libpod/pkg/rootless"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/devices"
spec "github.com/opencontainers/runtime-spec/specs-go"
@@ -118,8 +119,44 @@ func (c *CreateConfig) addPrivilegedDevices(g *generate.Generator) error {
return err
}
g.ClearLinuxDevices()
- for _, d := range hostDevices {
- g.AddDevice(Device(d))
+
+ if rootless.IsRootless() {
+ mounts := make(map[string]interface{})
+ for _, m := range g.Mounts() {
+ mounts[m.Destination] = true
+ }
+ newMounts := []spec.Mount{}
+ for _, d := range hostDevices {
+ devMnt := spec.Mount{
+ Destination: d.Path,
+ Type: TypeBind,
+ Source: d.Path,
+ Options: []string{"slave", "nosuid", "noexec", "rw", "rbind"},
+ }
+ if d.Path == "/dev/ptmx" || strings.HasPrefix(d.Path, "/dev/tty") {
+ continue
+ }
+ if _, found := mounts[d.Path]; found {
+ continue
+ }
+ st, err := os.Stat(d.Path)
+ if err != nil {
+ if err == unix.EPERM {
+ continue
+ }
+ return errors.Wrapf(err, "stat %s", d.Path)
+ }
+ // Skip devices that the user has not access to.
+ if st.Mode()&0007 == 0 {
+ continue
+ }
+ newMounts = append(newMounts, devMnt)
+ }
+ g.Config.Mounts = append(newMounts, g.Config.Mounts...)
+ } else {
+ for _, d := range hostDevices {
+ g.AddDevice(Device(d))
+ }
}
// Add resources device - need to clear the existing one first.
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index 41054633f..0f785df01 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -264,10 +264,8 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM
// If privileged, we need to add all the host devices to the
// spec. We do not add the user provided ones because we are
// already adding them all.
- if !rootless.IsRootless() {
- if err := config.AddPrivilegedDevices(&g); err != nil {
- return nil, err
- }
+ if err := config.AddPrivilegedDevices(&g); err != nil {
+ return nil, err
}
} else {
for _, devicePath := range config.Devices {
diff --git a/test/e2e/run_device_test.go b/test/e2e/run_device_test.go
index 2e537a9f9..cf7ce9cdf 100644
--- a/test/e2e/run_device_test.go
+++ b/test/e2e/run_device_test.go
@@ -85,4 +85,13 @@ var _ = Describe("Podman run device", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
+
+ It("podman run device host device with --privileged", func() {
+ if _, err := os.Stat("/dev/kvm"); err != nil {
+ Skip("/dev/kvm not available")
+ }
+ session := podmanTest.Podman([]string{"run", "--privileged", ALPINE, "ls", "/dev/kvm"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ })
})