pkg/libcontainer/mount/nodes/nodes.go
Timothy Hobbs 193f9894c0 Refactor device handling code
We now have one place that keeps track of (most) devices that are allowed and created within the container.  That place is pkg/libcontainer/devices/devices.go

This fixes several inconsistencies between which devices were created in the lxc backend and the native backend.  It also fixes inconsistencies between wich devices were created and which were allowed.  For example, /dev/full was being created but it was not allowed within the cgroup.  It also declares the file modes and permissions of the default devices, rather than copying them from the host.  This is in line with docker's philosphy of not being host dependent.

Docker-DCO-1.1-Signed-off-by: Timothy Hobbs <timothyhobbs@seznam.cz> (github: https://github.com/timthelion)
2014-05-30 19:21:29 +00:00

78 lines
1.8 KiB
Go

// +build linux
package nodes
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"syscall"
"github.com/dotcloud/docker/pkg/libcontainer/devices"
"github.com/dotcloud/docker/pkg/system"
)
// Create the device nodes in the container.
func CreateDeviceNodes(rootfs string, nodesToCreate []devices.Device) error {
oldMask := system.Umask(0000)
defer system.Umask(oldMask)
for _, node := range nodesToCreate {
if err := CreateDeviceNode(rootfs, node); err != nil {
return err
}
}
return nil
}
// Creates the device node in the rootfs of the container.
func CreateDeviceNode(rootfs string, node devices.Device) error {
var (
dest = filepath.Join(rootfs, node.Path)
parent = filepath.Dir(dest)
)
if err := os.MkdirAll(parent, 0755); err != nil {
return err
}
fileMode := node.FileMode
switch node.Type {
case 'c':
fileMode |= syscall.S_IFCHR
case 'b':
fileMode |= syscall.S_IFBLK
default:
return fmt.Errorf("%c is not a valid device type for device %s", node.Type, node.Path)
}
if err := system.Mknod(dest, uint32(fileMode), devices.Mkdev(node.MajorNumber, node.MinorNumber)); err != nil && !os.IsExist(err) {
return fmt.Errorf("mknod %s %s", node.Path, err)
}
return nil
}
func getDeviceNodes(path string) ([]string, error) {
out := []string{}
files, err := ioutil.ReadDir(path)
if err != nil {
return nil, err
}
for _, f := range files {
if f.IsDir() && f.Name() != "pts" && f.Name() != "shm" {
sub, err := getDeviceNodes(filepath.Join(path, f.Name()))
if err != nil {
return nil, err
}
out = append(out, sub...)
} else if f.Mode()&os.ModeDevice == os.ModeDevice {
out = append(out, filepath.Join(path, f.Name()))
}
}
return out, nil
}
func GetHostDeviceNodes() ([]string, error) {
return getDeviceNodes("/dev")
}