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
This commit is contained in:
parent
5bf2a4186a
commit
01ec3c5501
66
agent
66
agent
|
@ -56,6 +56,12 @@ REMOVABLE_VENDORS = [
|
||||||
REMOVABLE_PCI_VENDORS = [
|
REMOVABLE_PCI_VENDORS = [
|
||||||
"0x1044", "0x9004", "0x9005",
|
"0x1044", "0x9004", "0x9005",
|
||||||
]
|
]
|
||||||
|
# Set default data structure for SR-IOV
|
||||||
|
DEFAULT_SRIOV = {
|
||||||
|
"sriov_totalvfs" => 0,
|
||||||
|
"available" => false,
|
||||||
|
"pci_id" => ""
|
||||||
|
}
|
||||||
|
|
||||||
def digest(body)
|
def digest(body)
|
||||||
if body.is_a? Hash
|
if body.is_a? Hash
|
||||||
|
@ -267,6 +273,35 @@ class NodeAgent
|
||||||
res << Offloading.new(current, _parse_offloading(inner))
|
res << Offloading.new(current, _parse_offloading(inner))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Gets information about SR-IOV for specified pci slot
|
||||||
|
# using 'lspci' utility. Example of output to parse:
|
||||||
|
# ...
|
||||||
|
# Capabilities: [160 v1] Single Root I/O Virtualization (SR-IOV)
|
||||||
|
# IOVCap: Migration-, Interrupt Message Number: 000
|
||||||
|
# IOVCtl: Enable- Migration- Interrupt- MSE- ARIHierarchy-
|
||||||
|
# IOVSta: Migration-
|
||||||
|
# Initial VFs: 8, Total VFs: 8, Number of VFs: 0, Function Dependency Link: 01
|
||||||
|
# VF offset: 128, stride: 4, Device ID: 1520
|
||||||
|
# Supported Page Size: 00000553, System Page Size: 00000001
|
||||||
|
# Region 0: Memory at 0000000090040000 (64-bit, prefetchable)
|
||||||
|
# Region 3: Memory at 0000000090060000 (64-bit, prefetchable)
|
||||||
|
# VF Migration: offset: 00000000, BIR: 0
|
||||||
|
# ...
|
||||||
|
def sriov_info(int, int_bus_info)
|
||||||
|
sriov = DEFAULT_SRIOV.dup
|
||||||
|
lspci = _get_lspci_info(int_bus_info)
|
||||||
|
if lspci.match(/.*Capabilities:.*SR-IOV.*/)
|
||||||
|
sriov["available"] = true
|
||||||
|
sriov["sriov_totalvfs"] = lspci.scan(/\s+Total\s+VFs:\s+(\d+)/).last.first.to_i - 1
|
||||||
|
vf_vendor = File.read("/sys/class/net/#{int}/device/vendor").chomp.gsub(/^0x/, '')
|
||||||
|
vf_device = lspci.scan(/VF\s+.*\s+Device\s+ID:\s+(\d+)/).last.first
|
||||||
|
sriov["pci_id"] = "#{vf_vendor}:#{vf_device}"
|
||||||
|
end
|
||||||
|
sriov
|
||||||
|
rescue
|
||||||
|
DEFAULT_SRIOV
|
||||||
|
end
|
||||||
|
|
||||||
def _detailed
|
def _detailed
|
||||||
detailed_meta = {
|
detailed_meta = {
|
||||||
:system => _system_info,
|
:system => _system_info,
|
||||||
|
@ -295,8 +330,10 @@ class NodeAgent
|
||||||
# Avoid wireless
|
# Avoid wireless
|
||||||
next if File.exist?("/sys/class/net/#{int}/phy80211") ||
|
next if File.exist?("/sys/class/net/#{int}/phy80211") ||
|
||||||
File.exist?("/sys/class/net/#{int}/wireless")
|
File.exist?("/sys/class/net/#{int}/wireless")
|
||||||
|
# Skip virtual functions
|
||||||
|
next if File.exists?("/sys/class/net/#{int}/device/physfn")
|
||||||
int_meta = {:name => int}
|
int_meta = {:name => int}
|
||||||
|
int_meta[:interface_properties] = {}
|
||||||
int_meta[:state] = intinfo[:state]
|
int_meta[:state] = intinfo[:state]
|
||||||
(intinfo[:addresses] or {} rescue {}).each do |addr, addrinfo|
|
(intinfo[:addresses] or {} rescue {}).each do |addr, addrinfo|
|
||||||
if (addrinfo[:family] rescue nil) =~ /lladdr/
|
if (addrinfo[:family] rescue nil) =~ /lladdr/
|
||||||
|
@ -354,6 +391,8 @@ class NodeAgent
|
||||||
# return empty array to support nailgun's rest api call
|
# return empty array to support nailgun's rest api call
|
||||||
int_meta[:offloading_modes] = []
|
int_meta[:offloading_modes] = []
|
||||||
end
|
end
|
||||||
|
# Getting SR-IOV info
|
||||||
|
int_meta[:interface_properties][:sriov] = sriov_info(int, int_meta[:bus_info])
|
||||||
detailed_meta[:interfaces] << int_meta
|
detailed_meta[:interfaces] << int_meta
|
||||||
end
|
end
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
|
@ -853,9 +892,28 @@ class NodeAgent
|
||||||
end
|
end
|
||||||
|
|
||||||
def supported_hugepages
|
def supported_hugepages
|
||||||
return [2048, 1048576] if @os[:cpu]['0']['flags'].include?('pdpe1gb')
|
return [2048, 1048576] if @os[:cpu]['0']['flags'].include?('pdpe1gb')
|
||||||
return [2048] if @os[:cpu]['0']['flags'].include?('pse')
|
return [2048] if @os[:cpu]['0']['flags'].include?('pse')
|
||||||
[]
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
|
def _get_lspci_info(device)
|
||||||
|
lspci_path = `which lspci`.chomp
|
||||||
|
if $?.success?
|
||||||
|
data = `#{lspci_path} -vvv -s #{device}`
|
||||||
|
if $?.success?
|
||||||
|
return data
|
||||||
|
else
|
||||||
|
@logger.warn("Can't get data from lspci. Reason: lspci exited with status #{$?.exitstatus}")
|
||||||
|
""
|
||||||
|
end
|
||||||
|
else
|
||||||
|
@logger.warn("Can't find lspci. Reason: 'which lspci' returned exit status #{$?.exitstatus}")
|
||||||
|
""
|
||||||
|
end
|
||||||
|
rescue => e
|
||||||
|
@logger.warn("Can't get data from lspci for #{device} slot. Reason: #{e.message}")
|
||||||
|
""
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_state
|
def update_state
|
||||||
|
|
|
@ -11,7 +11,8 @@ Vcs-Browser: https://github.com/stackforge/fuel-nailgun-agent
|
||||||
Package: nailgun-agent
|
Package: nailgun-agent
|
||||||
Architecture: all
|
Architecture: all
|
||||||
XB-Ruby-Versions: ${ruby:Versions}
|
XB-Ruby-Versions: ${ruby:Versions}
|
||||||
Recommends: lshw
|
Recommends: lshw,
|
||||||
|
pciutils
|
||||||
Depends: ohai (<< 7),
|
Depends: ohai (<< 7),
|
||||||
dmidecode,
|
dmidecode,
|
||||||
ethtool,
|
ethtool,
|
||||||
|
|
Loading…
Reference in New Issue