Browse Source

Add support for SR-IOV enabled devices

- Skip Virtual Functions from list of interfaces
- Add SR-IOV related info for enabled devices to meta/interfaces

Change-Id: I62299123b7ba783544a0b7411d5ee95bcab726f3
Implements: blueprint #support-sriov
Implements: blueprint #sr-iov-in-nailgun-agent
Aleksandr Didenko 3 years ago
parent
commit
01ec3c5501
2 changed files with 64 additions and 5 deletions
  1. 62
    4
      agent
  2. 2
    1
      debian/control

+ 62
- 4
agent View File

@@ -56,6 +56,12 @@ REMOVABLE_VENDORS = [
56 56
 REMOVABLE_PCI_VENDORS = [
57 57
   "0x1044", "0x9004", "0x9005",
58 58
 ]
59
+# Set default data structure for SR-IOV
60
+DEFAULT_SRIOV = {
61
+  "sriov_totalvfs" => 0,
62
+  "available"      => false,
63
+  "pci_id"         => ""
64
+}
59 65
 
60 66
 def digest(body)
61 67
   if body.is_a? Hash
@@ -267,6 +273,35 @@ class NodeAgent
267 273
     res << Offloading.new(current, _parse_offloading(inner))
268 274
   end
269 275
 
276
+  # Gets information about SR-IOV for specified pci slot
277
+  # using 'lspci' utility. Example of output to parse:
278
+  #  ...
279
+  #  Capabilities: [160 v1] Single Root I/O Virtualization (SR-IOV)
280
+  #          IOVCap: Migration-, Interrupt Message Number: 000
281
+  #          IOVCtl: Enable- Migration- Interrupt- MSE- ARIHierarchy-
282
+  #          IOVSta: Migration-
283
+  #          Initial VFs: 8, Total VFs: 8, Number of VFs: 0, Function Dependency Link: 01
284
+  #          VF offset: 128, stride: 4, Device ID: 1520
285
+  #          Supported Page Size: 00000553, System Page Size: 00000001
286
+  #          Region 0: Memory at 0000000090040000 (64-bit, prefetchable)
287
+  #          Region 3: Memory at 0000000090060000 (64-bit, prefetchable)
288
+  #          VF Migration: offset: 00000000, BIR: 0
289
+  #  ...
290
+  def sriov_info(int, int_bus_info)
291
+    sriov = DEFAULT_SRIOV.dup
292
+    lspci = _get_lspci_info(int_bus_info)
293
+    if lspci.match(/.*Capabilities:.*SR-IOV.*/)
294
+      sriov["available"] = true
295
+      sriov["sriov_totalvfs"] = lspci.scan(/\s+Total\s+VFs:\s+(\d+)/).last.first.to_i - 1
296
+      vf_vendor = File.read("/sys/class/net/#{int}/device/vendor").chomp.gsub(/^0x/, '')
297
+      vf_device = lspci.scan(/VF\s+.*\s+Device\s+ID:\s+(\d+)/).last.first
298
+      sriov["pci_id"] = "#{vf_vendor}:#{vf_device}"
299
+    end
300
+    sriov
301
+  rescue
302
+    DEFAULT_SRIOV
303
+  end
304
+
270 305
   def _detailed
271 306
     detailed_meta = {
272 307
       :system => _system_info,
@@ -295,8 +330,10 @@ class NodeAgent
295 330
         # Avoid wireless
296 331
         next if File.exist?("/sys/class/net/#{int}/phy80211") ||
297 332
                 File.exist?("/sys/class/net/#{int}/wireless")
298
-
333
+        # Skip virtual functions
334
+        next if File.exists?("/sys/class/net/#{int}/device/physfn")
299 335
         int_meta = {:name => int}
336
+        int_meta[:interface_properties] = {}
300 337
         int_meta[:state] = intinfo[:state]
301 338
         (intinfo[:addresses] or {} rescue {}).each do |addr, addrinfo|
302 339
           if (addrinfo[:family] rescue nil) =~ /lladdr/
@@ -354,6 +391,8 @@ class NodeAgent
354 391
           # return empty array to support nailgun's rest api call
355 392
           int_meta[:offloading_modes] = []
356 393
         end
394
+        # Getting SR-IOV info
395
+        int_meta[:interface_properties][:sriov] = sriov_info(int, int_meta[:bus_info])
357 396
         detailed_meta[:interfaces] << int_meta
358 397
       end
359 398
     rescue Exception => e
@@ -853,9 +892,28 @@ class NodeAgent
853 892
   end
854 893
 
855 894
   def supported_hugepages
856
-      return [2048, 1048576] if @os[:cpu]['0']['flags'].include?('pdpe1gb')
857
-      return [2048] if @os[:cpu]['0']['flags'].include?('pse')
858
-      []
895
+    return [2048, 1048576] if @os[:cpu]['0']['flags'].include?('pdpe1gb')
896
+    return [2048] if @os[:cpu]['0']['flags'].include?('pse')
897
+    []
898
+  end
899
+
900
+  def _get_lspci_info(device)
901
+    lspci_path = `which lspci`.chomp
902
+    if $?.success?
903
+      data = `#{lspci_path} -vvv -s #{device}`
904
+      if $?.success?
905
+        return data
906
+      else
907
+        @logger.warn("Can't get data from lspci. Reason: lspci exited with status #{$?.exitstatus}")
908
+        ""
909
+      end
910
+    else
911
+      @logger.warn("Can't find lspci. Reason: 'which lspci' returned exit status #{$?.exitstatus}")
912
+      ""
913
+    end
914
+  rescue => e
915
+    @logger.warn("Can't get data from lspci for #{device} slot. Reason: #{e.message}")
916
+    ""
859 917
   end
860 918
 
861 919
   def update_state

+ 2
- 1
debian/control View File

@@ -11,7 +11,8 @@ Vcs-Browser: https://github.com/stackforge/fuel-nailgun-agent
11 11
 Package: nailgun-agent
12 12
 Architecture: all
13 13
 XB-Ruby-Versions: ${ruby:Versions}
14
-Recommends: lshw
14
+Recommends: lshw,
15
+            pciutils
15 16
 Depends: ohai (<< 7),
16 17
          dmidecode,
17 18
          ethtool,

Loading…
Cancel
Save