@@ -21,6 +21,7 @@ package cdi
2121import (
2222 "errors"
2323 "fmt"
24+ "os"
2425
2526 "golang.org/x/sys/unix"
2627)
@@ -31,16 +32,28 @@ const (
3132 fifoDevice = "p"
3233)
3334
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+
3445// deviceInfoFromPath takes the path to a device and returns its type,
3546// major and minor device numbers.
3647//
3748// 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 ) {
3950 var stat unix.Stat_t
4051 err := unix .Lstat (path , & stat )
4152 if err != nil {
42- return "" , 0 , 0 , err
53+ return nil , err
4354 }
55+
56+ var devType string
4457 switch stat .Mode & unix .S_IFMT {
4558 case unix .S_IFBLK :
4659 devType = blockDevice
@@ -49,10 +62,18 @@ func deviceInfoFromPath(path string) (devType string, major, minor int64, _ erro
4962 case unix .S_IFIFO :
5063 devType = fifoDevice
5164 default :
52- return "" , 0 , 0 , errors .New ("not a device node" )
65+ return nil , errors .New ("not a device node" )
5366 }
5467 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
5677}
5778
5879// fillMissingInfo fills in missing mandatory attributes from the host device.
@@ -65,22 +86,31 @@ func (d *DeviceNode) fillMissingInfo() error {
6586 return nil
6687 }
6788
68- deviceType , major , minor , err := deviceInfoFromPath (d .HostPath )
89+ di , err := deviceInfoFromPath (d .HostPath )
6990 if err != nil {
7091 return fmt .Errorf ("failed to stat CDI host device %q: %w" , d .HostPath , err )
7192 }
7293
7394 if d .Type == "" {
74- d .Type = deviceType
95+ d .Type = di . deviceType
7596 } else {
76- if d .Type != deviceType {
97+ if d .Type != di . deviceType {
7798 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 )
79100 }
80101 }
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
84114 }
85115
86116 return nil
0 commit comments