aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/opencontainers/runc/libcontainer/devices/device.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/opencontainers/runc/libcontainer/devices/device.go')
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/devices/device.go170
1 files changed, 170 insertions, 0 deletions
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/devices/device.go b/vendor/github.com/opencontainers/runc/libcontainer/devices/device.go
new file mode 100644
index 000000000..3eb73cc7c
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/libcontainer/devices/device.go
@@ -0,0 +1,170 @@
+package devices
+
+import (
+ "fmt"
+ "os"
+ "strconv"
+)
+
+const (
+ Wildcard = -1
+)
+
+type Device struct {
+ Rule
+
+ // Path to the device.
+ Path string `json:"path"`
+
+ // 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"`
+}
+
+// Permissions is a cgroupv1-style string to represent device access. It
+// has to be a string for backward compatibility reasons, hence why it has
+// methods to do set operations.
+type Permissions string
+
+const (
+ deviceRead uint = (1 << iota)
+ deviceWrite
+ deviceMknod
+)
+
+func (p Permissions) toSet() uint {
+ var set uint
+ for _, perm := range p {
+ switch perm {
+ case 'r':
+ set |= deviceRead
+ case 'w':
+ set |= deviceWrite
+ case 'm':
+ set |= deviceMknod
+ }
+ }
+ return set
+}
+
+func fromSet(set uint) Permissions {
+ var perm string
+ if set&deviceRead == deviceRead {
+ perm += "r"
+ }
+ if set&deviceWrite == deviceWrite {
+ perm += "w"
+ }
+ if set&deviceMknod == deviceMknod {
+ perm += "m"
+ }
+ return Permissions(perm)
+}
+
+// Union returns the union of the two sets of Permissions.
+func (p Permissions) Union(o Permissions) Permissions {
+ lhs := p.toSet()
+ rhs := o.toSet()
+ return fromSet(lhs | rhs)
+}
+
+// Difference returns the set difference of the two sets of Permissions.
+// In set notation, A.Difference(B) gives you A\B.
+func (p Permissions) Difference(o Permissions) Permissions {
+ lhs := p.toSet()
+ rhs := o.toSet()
+ return fromSet(lhs &^ rhs)
+}
+
+// Intersection computes the intersection of the two sets of Permissions.
+func (p Permissions) Intersection(o Permissions) Permissions {
+ lhs := p.toSet()
+ rhs := o.toSet()
+ return fromSet(lhs & rhs)
+}
+
+// IsEmpty returns whether the set of permissions in a Permissions is
+// empty.
+func (p Permissions) IsEmpty() bool {
+ return p == Permissions("")
+}
+
+// IsValid returns whether the set of permissions is a subset of valid
+// permissions (namely, {r,w,m}).
+func (p Permissions) IsValid() bool {
+ return p == fromSet(p.toSet())
+}
+
+type Type rune
+
+const (
+ WildcardDevice Type = 'a'
+ BlockDevice Type = 'b'
+ CharDevice Type = 'c' // or 'u'
+ FifoDevice Type = 'p'
+)
+
+func (t Type) IsValid() bool {
+ switch t {
+ case WildcardDevice, BlockDevice, CharDevice, FifoDevice:
+ return true
+ default:
+ return false
+ }
+}
+
+func (t Type) CanMknod() bool {
+ switch t {
+ case BlockDevice, CharDevice, FifoDevice:
+ return true
+ default:
+ return false
+ }
+}
+
+func (t Type) CanCgroup() bool {
+ switch t {
+ case WildcardDevice, BlockDevice, CharDevice:
+ return true
+ default:
+ return false
+ }
+}
+
+type Rule struct {
+ // Type of device ('c' for char, 'b' for block). If set to 'a', this rule
+ // acts as a wildcard and all fields other than Allow are ignored.
+ Type Type `json:"type"`
+
+ // Major is the device's major number.
+ Major int64 `json:"major"`
+
+ // Minor is the device's minor number.
+ Minor int64 `json:"minor"`
+
+ // Permissions is the set of permissions that this rule applies to (in the
+ // cgroupv1 format -- any combination of "rwm").
+ Permissions Permissions `json:"permissions"`
+
+ // Allow specifies whether this rule is allowed.
+ Allow bool `json:"allow"`
+}
+
+func (d *Rule) CgroupString() string {
+ var (
+ major = strconv.FormatInt(d.Major, 10)
+ minor = strconv.FormatInt(d.Minor, 10)
+ )
+ if d.Major == Wildcard {
+ major = "*"
+ }
+ if d.Minor == Wildcard {
+ minor = "*"
+ }
+ return fmt.Sprintf("%c %s:%s %s", d.Type, major, minor, d.Permissions)
+}