@@ -21,6 +21,7 @@ package cdi
21
21
import (
22
22
"errors"
23
23
"fmt"
24
+ "os"
24
25
25
26
"golang.org/x/sys/unix"
26
27
)
@@ -31,16 +32,28 @@ const (
31
32
fifoDevice = "p"
32
33
)
33
34
35
+ type deviceInfo struct {
36
+ // cgroup properties
37
+ deviceType string
38
+ major int64
39
+ minor int64
40
+
41
+ // device node properties
42
+ fileMode os.FileMode
43
+ }
44
+
34
45
// deviceInfoFromPath takes the path to a device and returns its type,
35
46
// major and minor device numbers.
36
47
//
37
48
// It was adapted from https://github.com/opencontainers/runc/blob/v1.1.9/libcontainer/devices/device_unix.go#L30-L69
38
- func deviceInfoFromPath (path string ) (devType string , major , minor int64 , _ error ) {
49
+ func deviceInfoFromPath (path string ) (* deviceInfo , error ) {
39
50
var stat unix.Stat_t
40
51
err := unix .Lstat (path , & stat )
41
52
if err != nil {
42
- return "" , 0 , 0 , err
53
+ return nil , err
43
54
}
55
+
56
+ var devType string
44
57
switch stat .Mode & unix .S_IFMT {
45
58
case unix .S_IFBLK :
46
59
devType = blockDevice
@@ -49,10 +62,18 @@ func deviceInfoFromPath(path string) (devType string, major, minor int64, _ erro
49
62
case unix .S_IFIFO :
50
63
devType = fifoDevice
51
64
default :
52
- return "" , 0 , 0 , errors .New ("not a device node" )
65
+ return nil , errors .New ("not a device node" )
53
66
}
54
67
devNumber := uint64 (stat .Rdev ) //nolint:unconvert // Rdev is uint32 on e.g. MIPS.
55
- return devType , int64 (unix .Major (devNumber )), int64 (unix .Minor (devNumber )), nil
68
+
69
+ di := deviceInfo {
70
+ deviceType : devType ,
71
+ major : int64 (unix .Major (devNumber )),
72
+ minor : int64 (unix .Minor (devNumber )),
73
+ fileMode : os .FileMode (stat .Mode &^ unix .S_IFMT ),
74
+ }
75
+
76
+ return & di , nil
56
77
}
57
78
58
79
// fillMissingInfo fills in missing mandatory attributes from the host device.
@@ -65,22 +86,31 @@ func (d *DeviceNode) fillMissingInfo() error {
65
86
return nil
66
87
}
67
88
68
- deviceType , major , minor , err := deviceInfoFromPath (d .HostPath )
89
+ di , err := deviceInfoFromPath (d .HostPath )
69
90
if err != nil {
70
91
return fmt .Errorf ("failed to stat CDI host device %q: %w" , d .HostPath , err )
71
92
}
72
93
73
94
if d .Type == "" {
74
- d .Type = deviceType
95
+ d .Type = di . deviceType
75
96
} else {
76
- if d .Type != deviceType {
97
+ if d .Type != di . deviceType {
77
98
return fmt .Errorf ("CDI device (%q, %q), host type mismatch (%s, %s)" ,
78
- d .Path , d .HostPath , d .Type , deviceType )
99
+ d .Path , d .HostPath , d .Type , di . deviceType )
79
100
}
80
101
}
81
- if d .Major == 0 && d .Type != "p" {
82
- d .Major = major
83
- d .Minor = minor
102
+
103
+ if d .FileMode == nil {
104
+ d .FileMode = & di .fileMode
105
+ }
106
+
107
+ if d .Type == "p" {
108
+ return nil
109
+ }
110
+
111
+ if d .Major == 0 {
112
+ d .Major = di .major
113
+ d .Minor = di .minor
84
114
}
85
115
86
116
return nil
0 commit comments