@@ -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