add recursive device nodes

Docker-DCO-1.1-Signed-off-by: Victor Vieux <vieux@docker.com> (github: vieux)
This commit is contained in:
Victor Vieux 2014-05-22 19:14:10 +00:00
parent 89b64d33ee
commit bf21f0d493

View file

@ -14,12 +14,12 @@ import (
// Default list of device nodes to copy // Default list of device nodes to copy
var DefaultNodes = []string{ var DefaultNodes = []string{
"null", "/dev/null",
"zero", "/dev/zero",
"full", "/dev/full",
"random", "/dev/random",
"urandom", "/dev/urandom",
"tty", "/dev/tty",
} }
// CopyN copies the device node from the host into the rootfs // CopyN copies the device node from the host into the rootfs
@ -39,7 +39,7 @@ func CopyN(rootfs string, nodesToCopy []string, shouldExist bool) error {
// on the host system does not exist and the boolean flag is passed // on the host system does not exist and the boolean flag is passed
// an error will be returned // an error will be returned
func Copy(rootfs, node string, shouldExist bool) error { func Copy(rootfs, node string, shouldExist bool) error {
stat, err := os.Stat(filepath.Join("/dev", node)) stat, err := os.Stat(node)
if err != nil { if err != nil {
if os.IsNotExist(err) && !shouldExist { if os.IsNotExist(err) && !shouldExist {
return nil return nil
@ -48,27 +48,41 @@ func Copy(rootfs, node string, shouldExist bool) error {
} }
var ( var (
dest = filepath.Join(rootfs, "dev", node) dest = filepath.Join(rootfs, node)
st = stat.Sys().(*syscall.Stat_t) st = stat.Sys().(*syscall.Stat_t)
parent = filepath.Dir(dest)
) )
if err := os.MkdirAll(parent, 0755); err != nil {
return err
}
if err := system.Mknod(dest, st.Mode, int(st.Rdev)); err != nil && !os.IsExist(err) { if err := system.Mknod(dest, st.Mode, int(st.Rdev)); err != nil && !os.IsExist(err) {
return fmt.Errorf("mknod %s %s", node, err) return fmt.Errorf("mknod %s %s", node, err)
} }
return nil return nil
} }
func GetHostDeviceNodes() ([]string, error) { func getNodes(path string) ([]string, error) {
files, err := ioutil.ReadDir("/dev") out := []string{}
files, err := ioutil.ReadDir(path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
out := []string{}
for _, f := range files { for _, f := range files {
if f.Mode()&os.ModeDevice == os.ModeDevice { if f.IsDir() && f.Name() != "pts" && f.Name() != "shm" {
out = append(out, f.Name()) sub, err := getNodes(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 return out, nil
} }
func GetHostDeviceNodes() ([]string, error) {
return getNodes("/dev")
}