code: func generateDeviceAllows(root string, appName types.ACName, mountPoints []types.MountPoint, mounts []Mount, uidRange *user.UidRange) ([]string, error) {
  	var devAllow []string
  
  	rktVolumeLinksPath := filepath.Join(root, "rkt", "volumes")
  	if err := os.MkdirAll(rktVolumeLinksPath, 0600); err != nil {
  		return nil, err
  	}
  	if err := user.ShiftFiles([]string{rktVolumeLinksPath}, uidRange); err != nil {
  		return nil, err
  	}
  
  	for _, m := range mounts {
  		if m.Volume.Kind != "host" {
  			continue
  		}
  		if fileutil.IsDeviceNode(m.Volume.Source) {
  			mode := "r"
  			if !m.ReadOnly {
  				mode += "w"
  			}
  
  			tgt := filepath.Join(common.RelAppRootfsPath(appName), m.Mount.Path)
  			// the DeviceAllow= line needs the link path in /dev/.rkt/
  			linkRel := filepath.Join("/dev/.rkt", m.Volume.Name.String())
  			// the real link should be in /rkt/volumes for now
  			link := filepath.Join(rktVolumeLinksPath, m.Volume.Name.String())
  
  			err := os.Symlink(tgt, link)
  			// if the link already exists, we don't need to do anything
  			if err != nil && !os.IsExist(err) {
  				return nil, err
  			}
  
  			devAllow = append(devAllow, linkRel+" "+mode)
  		}
  	}
  
  	return devAllow, nil
  }
docs: // generateDeviceAllows generates a DeviceAllow= line for an app.
  // To make it work, the path needs to start with "/dev" but the device won't
  // exist inside the container. So for a given mount, if the volume is a device
  // node, we create a symlink to its target in "/rkt/volumes". Later,
  // prepare-app will copy those to "/dev/.rkt/" so that's what we use in the
  // DeviceAllow= line.