-
Notifications
You must be signed in to change notification settings - Fork 6
/
devices.go
89 lines (70 loc) · 1.88 KB
/
devices.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
// Device information
type Device struct {
// Device type, block, char, etc.
Type rune `json:"type"`
// Path to the device.
Path string `json:"path"`
// Major is the device's major number.
Major int64 `json:"major"`
// Minor is the device's minor number.
Minor int64 `json:"minor"`
// Cgroup permissions format, rwm.
Permissions string `json:"permissions"`
// FileMode permission bits for the device.
FileMode os.FileMode `json:"file_mode"`
// Uid of the device.
Uid uint32 `json:"uid"`
// Gid of the device.
Gid uint32 `json:"gid"`
// Write the file to the allowed list
Allow bool `json:"allow"`
}
func createDeviceNode(rootfs string, node *Device) error {
dest := filepath.Join(rootfs, node.Path)
if err := os.MkdirAll(filepath.Dir(dest), 0755); err != nil {
return err
}
return mknodDevice(dest, node)
}
func mknodDevice(dest string, node *Device) error {
fileMode := node.FileMode
switch node.Type {
case 'c', 'u':
fileMode |= unix.S_IFCHR
case 'b':
fileMode |= unix.S_IFBLK
case 'p':
fileMode |= unix.S_IFIFO
default:
return fmt.Errorf("%c is not a valid device type for device %s", node.Type, node.Path)
}
dNum := int((node.Major << 8) | (node.Minor & 0xff) | ((node.Minor & 0xfff00) << 12))
if err := unix.Mknod(dest, uint32(fileMode), dNum); err != nil {
return err
}
return unix.Chown(dest, int(node.Uid), int(node.Gid))
}
func openRootfsFd(file string) (*os.File, bool) {
fd, err := os.OpenFile(file, os.O_RDWR, 0666)
if err != nil {
logrus.Errorf("open %s error: /dev/%s\n", file, err)
panic(err)
}
return fd, true
}
func openJsonFd(file string) (*os.File, bool) {
fd, err := os.OpenFile(file, os.O_RDONLY, unix.S_IRUSR|unix.S_IWUSR)
if err != nil {
logrus.Errorf("open %s error: %s\n", file, err)
panic(err)
}
return fd, false
}