mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	Mounting a directory of devices like /dev/snd should mount all child devices.
I have seen a lot of people try to do this and reach out to me on how to mount /dev/snd because it is returning "not a device node". The docs imply you can _just_ mount /dev/snd and that is not the case. This fixes that. It also allows for coolness if you want to mount say /dev/usb. Docker-DCO-1.1-Signed-off-by: Jessie Frazelle <hugs@docker.com> (github: jfrazelle) Docker-DCO-1.1-Signed-off-by: Jessie Frazelle <princess@docker.com> (github: jfrazelle) Docker-DCO-1.1-Signed-off-by: Jessie Frazelle <jess@docker.com> (github: jfrazelle) Docker-DCO-1.1-Signed-off-by: Jessica Frazelle <jess@docker.com> (github: jfrazelle)
This commit is contained in:
		
							parent
							
								
									3fe7a3d537
								
							
						
					
					
						commit
						664004ed0c
					
				
					 2 changed files with 72 additions and 6 deletions
				
			
		| 
						 | 
				
			
			@ -215,6 +215,45 @@ func (container *Container) getRootResourcePath(path string) (string, error) {
 | 
			
		|||
	return symlink.FollowSymlinkInScope(filepath.Join(container.root, cleanPath), container.root)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getDevicesFromPath(deviceMapping runconfig.DeviceMapping) (devs []*configs.Device, err error) {
 | 
			
		||||
	device, err := devices.DeviceFromPath(deviceMapping.PathOnHost, deviceMapping.CgroupPermissions)
 | 
			
		||||
	// if there was no error, return the device
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		device.Path = deviceMapping.PathInContainer
 | 
			
		||||
		return append(devs, device), nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// if the device is not a device node
 | 
			
		||||
	// try to see if it's a directory holding many devices
 | 
			
		||||
	if err == devices.ErrNotADevice {
 | 
			
		||||
 | 
			
		||||
		// check if it is a directory
 | 
			
		||||
		if src, e := os.Stat(deviceMapping.PathOnHost); e == nil && src.IsDir() {
 | 
			
		||||
 | 
			
		||||
			// mount the internal devices recursively
 | 
			
		||||
			filepath.Walk(deviceMapping.PathOnHost, func(dpath string, f os.FileInfo, e error) error {
 | 
			
		||||
				childDevice, e := devices.DeviceFromPath(dpath, deviceMapping.CgroupPermissions)
 | 
			
		||||
				if e != nil {
 | 
			
		||||
					// ignore the device
 | 
			
		||||
					return nil
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// add the device to userSpecified devices
 | 
			
		||||
				childDevice.Path = strings.Replace(dpath, deviceMapping.PathOnHost, deviceMapping.PathInContainer, 1)
 | 
			
		||||
				devs = append(devs, childDevice)
 | 
			
		||||
 | 
			
		||||
				return nil
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(devs) > 0 {
 | 
			
		||||
		return devs, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return devs, fmt.Errorf("error gathering device information while adding custom device %q: %s", deviceMapping.PathOnHost, err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func populateCommand(c *Container, env []string) error {
 | 
			
		||||
	en := &execdriver.Network{
 | 
			
		||||
		Mtu:       c.daemon.config.Mtu,
 | 
			
		||||
| 
						 | 
				
			
			@ -267,14 +306,14 @@ func populateCommand(c *Container, env []string) error {
 | 
			
		|||
	pid.HostPid = c.hostConfig.PidMode.IsHost()
 | 
			
		||||
 | 
			
		||||
	// Build lists of devices allowed and created within the container.
 | 
			
		||||
	userSpecifiedDevices := make([]*configs.Device, len(c.hostConfig.Devices))
 | 
			
		||||
	for i, deviceMapping := range c.hostConfig.Devices {
 | 
			
		||||
		device, err := devices.DeviceFromPath(deviceMapping.PathOnHost, deviceMapping.CgroupPermissions)
 | 
			
		||||
	var userSpecifiedDevices []*configs.Device
 | 
			
		||||
	for _, deviceMapping := range c.hostConfig.Devices {
 | 
			
		||||
		devs, err := getDevicesFromPath(deviceMapping)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return fmt.Errorf("error gathering device information while adding custom device %q: %s", deviceMapping.PathOnHost, err)
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		device.Path = deviceMapping.PathInContainer
 | 
			
		||||
		userSpecifiedDevices[i] = device
 | 
			
		||||
 | 
			
		||||
		userSpecifiedDevices = append(userSpecifiedDevices, devs...)
 | 
			
		||||
	}
 | 
			
		||||
	allowedDevices := append(configs.DefaultAllowedDevices, userSpecifiedDevices...)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -173,3 +173,30 @@ func TestRunContainerWithCgroupParentAbsPath(t *testing.T) {
 | 
			
		|||
 | 
			
		||||
	logDone("run - cgroup parent with absolute cgroup path")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestRunDeviceDirectory(t *testing.T) {
 | 
			
		||||
	defer deleteAllContainers()
 | 
			
		||||
	cmd := exec.Command(dockerBinary, "run", "--device", "/dev/snd:/dev/snd", "busybox", "sh", "-c", "ls /dev/snd/")
 | 
			
		||||
 | 
			
		||||
	out, _, err := runCommandWithOutput(cmd)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err, out)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if actual := strings.Trim(out, "\r\n"); !strings.Contains(out, "timer") {
 | 
			
		||||
		t.Fatalf("expected output /dev/snd/timer, received %s", actual)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cmd = exec.Command(dockerBinary, "run", "--device", "/dev/snd:/dev/othersnd", "busybox", "sh", "-c", "ls /dev/othersnd/")
 | 
			
		||||
 | 
			
		||||
	out, _, err = runCommandWithOutput(cmd)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err, out)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if actual := strings.Trim(out, "\r\n"); !strings.Contains(out, "seq") {
 | 
			
		||||
		t.Fatalf("expected output /dev/othersnd/timer, received %s", actual)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logDone("run - test --device directory mounts all internal devices")
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue