@@ -84,6 +84,169 @@ type DevlinkDeviceInfo struct {
84
84
FwUndi string
85
85
}
86
86
87
+ // DevlinkResource represents a device resource
88
+ type DevlinkResource struct {
89
+ Name string
90
+ ID uint64
91
+ Size uint64
92
+ SizeNew uint64
93
+ SizeMin uint64
94
+ SizeMax uint64
95
+ SizeGranularity uint64
96
+ PendingChange bool
97
+ Unit uint8
98
+ SizeValid bool
99
+ OCCValid bool
100
+ OCCSize uint64
101
+ Parent * DevlinkResource
102
+ Children []DevlinkResource
103
+ }
104
+
105
+ // parseAttributes parses provided Netlink Attributes and populates DevlinkResource, returns error if occured
106
+ func (dlr * DevlinkResource ) parseAttributes (attrs map [uint16 ]syscall.NetlinkRouteAttr ) error {
107
+ var attr syscall.NetlinkRouteAttr
108
+ var ok bool
109
+
110
+ // mandatory attributes
111
+ attr , ok = attrs [nl .DEVLINK_ATTR_RESOURCE_ID ]
112
+ if ! ok {
113
+ return fmt .Errorf ("missing resource id" )
114
+ }
115
+ dlr .ID = native .Uint64 (attr .Value )
116
+
117
+ attr , ok = attrs [nl .DEVLINK_ATTR_RESOURCE_NAME ]
118
+ if ! ok {
119
+ return fmt .Errorf ("missing resource name" )
120
+ }
121
+ dlr .Name = nl .BytesToString (attr .Value )
122
+
123
+ attr , ok = attrs [nl .DEVLINK_ATTR_RESOURCE_SIZE ]
124
+ if ! ok {
125
+ return fmt .Errorf ("missing resource size" )
126
+ }
127
+ dlr .Size = native .Uint64 (attr .Value )
128
+
129
+ attr , ok = attrs [nl .DEVLINK_ATTR_RESOURCE_SIZE_GRAN ]
130
+ if ! ok {
131
+ return fmt .Errorf ("missing resource size granularity" )
132
+ }
133
+ dlr .SizeGranularity = native .Uint64 (attr .Value )
134
+
135
+ attr , ok = attrs [nl .DEVLINK_ATTR_RESOURCE_UNIT ]
136
+ if ! ok {
137
+ return fmt .Errorf ("missing resource unit" )
138
+ }
139
+ dlr .Unit = uint8 (attr .Value [0 ])
140
+
141
+ attr , ok = attrs [nl .DEVLINK_ATTR_RESOURCE_SIZE_MIN ]
142
+ if ! ok {
143
+ return fmt .Errorf ("missing resource size min" )
144
+ }
145
+ dlr .SizeMin = native .Uint64 (attr .Value )
146
+
147
+ attr , ok = attrs [nl .DEVLINK_ATTR_RESOURCE_SIZE_MAX ]
148
+ if ! ok {
149
+ return fmt .Errorf ("missing resource size max" )
150
+ }
151
+ dlr .SizeMax = native .Uint64 (attr .Value )
152
+
153
+ // optional attributes
154
+ attr , ok = attrs [nl .DEVLINK_ATTR_RESOURCE_OCC ]
155
+ if ok {
156
+ dlr .OCCSize = native .Uint64 (attr .Value )
157
+ dlr .OCCValid = true
158
+ }
159
+
160
+ attr , ok = attrs [nl .DEVLINK_ATTR_RESOURCE_SIZE_VALID ]
161
+ if ok {
162
+ dlr .SizeValid = uint8 (attr .Value [0 ]) != 0
163
+ }
164
+
165
+ dlr .SizeNew = dlr .Size
166
+ attr , ok = attrs [nl .DEVLINK_ATTR_RESOURCE_SIZE_NEW ]
167
+ if ok {
168
+ dlr .SizeNew = native .Uint64 (attr .Value )
169
+ }
170
+
171
+ dlr .PendingChange = dlr .Size != dlr .SizeNew
172
+
173
+ attr , ok = attrs [nl .DEVLINK_ATTR_RESOURCE_LIST ]
174
+ if ok {
175
+ // handle nested resoruces recursively
176
+ subResources , err := nl .ParseRouteAttr (attr .Value )
177
+ if err != nil {
178
+ return err
179
+ }
180
+
181
+ for _ , subresource := range subResources {
182
+ resource := DevlinkResource {Parent : dlr }
183
+ attrs , err := nl .ParseRouteAttrAsMap (subresource .Value )
184
+ if err != nil {
185
+ return err
186
+ }
187
+ err = resource .parseAttributes (attrs )
188
+ if err != nil {
189
+ return fmt .Errorf ("failed to parse child resource, parent:%s. %w" , dlr .Name , err )
190
+ }
191
+ dlr .Children = append (dlr .Children , resource )
192
+ }
193
+ }
194
+ return nil
195
+ }
196
+
197
+ // DevlinkResources represents all devlink resources of a devlink device
198
+ type DevlinkResources struct {
199
+ Bus string
200
+ Device string
201
+ Resources []DevlinkResource
202
+ }
203
+
204
+ // parseAttributes parses provided Netlink Attributes and populates DevlinkResources, returns error if occured
205
+ func (dlrs * DevlinkResources ) parseAttributes (attrs map [uint16 ]syscall.NetlinkRouteAttr ) error {
206
+ var attr syscall.NetlinkRouteAttr
207
+ var ok bool
208
+
209
+ // Bus
210
+ attr , ok = attrs [nl .DEVLINK_ATTR_BUS_NAME ]
211
+ if ! ok {
212
+ return fmt .Errorf ("missing bus name" )
213
+ }
214
+ dlrs .Bus = nl .BytesToString (attr .Value )
215
+
216
+ // Device
217
+ attr , ok = attrs [nl .DEVLINK_ATTR_DEV_NAME ]
218
+ if ! ok {
219
+ return fmt .Errorf ("missing device name" )
220
+ }
221
+ dlrs .Device = nl .BytesToString (attr .Value )
222
+
223
+ // Resource List
224
+ attr , ok = attrs [nl .DEVLINK_ATTR_RESOURCE_LIST ]
225
+ if ! ok {
226
+ return fmt .Errorf ("missing resource list" )
227
+ }
228
+
229
+ resourceAttrs , err := nl .ParseRouteAttr (attr .Value )
230
+ if err != nil {
231
+ return err
232
+ }
233
+
234
+ for _ , resourceAttr := range resourceAttrs {
235
+ resource := DevlinkResource {}
236
+ attrs , err := nl .ParseRouteAttrAsMap (resourceAttr .Value )
237
+ if err != nil {
238
+ return err
239
+ }
240
+ err = resource .parseAttributes (attrs )
241
+ if err != nil {
242
+ return fmt .Errorf ("failed to parse root resoruces, %w" , err )
243
+ }
244
+ dlrs .Resources = append (dlrs .Resources , resource )
245
+ }
246
+
247
+ return nil
248
+ }
249
+
87
250
func parseDevLinkDeviceList (msgs [][]byte ) ([]* DevlinkDevice , error ) {
88
251
devices := make ([]* DevlinkDevice , 0 , len (msgs ))
89
252
for _ , m := range msgs {
@@ -443,6 +606,35 @@ func (h *Handle) DevLinkGetPortByIndex(Bus string, Device string, PortIndex uint
443
606
return port , err
444
607
}
445
608
609
+ // DevlinkGetDeviceResources returns devlink device resources
610
+ func DevlinkGetDeviceResources (bus string , device string ) (* DevlinkResources , error ) {
611
+ return pkgHandle .DevlinkGetDeviceResources (bus , device )
612
+ }
613
+
614
+ // DevlinkGetDeviceResources returns devlink device resources
615
+ func (h * Handle ) DevlinkGetDeviceResources (bus string , device string ) (* DevlinkResources , error ) {
616
+ _ , req , err := h .createCmdReq (nl .DEVLINK_CMD_RESOURCE_DUMP , bus , device )
617
+ if err != nil {
618
+ return nil , err
619
+ }
620
+
621
+ respmsg , err := req .Execute (unix .NETLINK_GENERIC , 0 )
622
+ if err != nil {
623
+ return nil , err
624
+ }
625
+
626
+ var resources DevlinkResources
627
+ for _ , m := range respmsg {
628
+ attrs , err := nl .ParseRouteAttrAsMap (m [nl .SizeofGenlmsg :])
629
+ if err != nil {
630
+ return nil , err
631
+ }
632
+ resources .parseAttributes (attrs )
633
+ }
634
+
635
+ return & resources , nil
636
+ }
637
+
446
638
// DevLinkGetPortByIndex provides a pointer to devlink portand nil error,
447
639
// otherwise returns an error code.
448
640
func DevLinkGetPortByIndex (Bus string , Device string , PortIndex uint32 ) (* DevlinkPort , error ) {
0 commit comments