mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-29 18:50:08 +03:00
F #6028: Update operation for VF.
Attributes that can be updated through the network: - VLAN_ID - SPOOFCHK - TRUST * OpenNebula core changes add the previous attributes to VNET_UPDATE. And removes constraint on updating non-pci NICs * VF class includes an update method equivalent to activate_vf. Common code has been moved to a separate function * Drivers: 802.1Q, bridge, fw, and ovswitch calls update_vf function
This commit is contained in:
parent
00549961bc
commit
d6895c4716
@ -2154,7 +2154,7 @@ int VirtualMachine::nic_update(int vnid)
|
||||
|
||||
for (auto nic : nics)
|
||||
{
|
||||
if (nic->is_alias() || nic->is_pci())
|
||||
if (nic->is_alias())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -476,7 +476,10 @@ void VirtualNetwork::set_updated_attributes(Template* new_tmpl, bool removed)
|
||||
"INBOUND_PEAK_KB",
|
||||
"OUTBOUND_AVG_BW",
|
||||
"OUTBOUND_PEAK_BW",
|
||||
"OUTBOUND_PEAK_KB"
|
||||
"OUTBOUND_PEAK_KB",
|
||||
//SRIOV
|
||||
"SPOOFCHK",
|
||||
"TRUST"
|
||||
};
|
||||
|
||||
// Adds list of updated values to "VNET_UPDATE" attribute in the
|
||||
|
@ -39,8 +39,8 @@ begin
|
||||
deploy_id)
|
||||
filter_driver.update(vn_id)
|
||||
|
||||
# TODO: Implement update for vf
|
||||
# filter_driver.activate_vf(filter_driver.vm)
|
||||
# VF - Related changes
|
||||
filter_driver.update_vf(filter_driver.vm, vn_id)
|
||||
rescue StandardError => e
|
||||
OpenNebula.log_error(e.message)
|
||||
OpenNebula.log_error(e.backtrace)
|
||||
|
@ -21,9 +21,10 @@ $LOAD_PATH << File.join(File.dirname(__FILE__), '..')
|
||||
|
||||
require 'vnmmad'
|
||||
|
||||
template64 = STDIN.read
|
||||
template64 = STDIN.read
|
||||
xpath_filter = "TEMPLATE/NIC[VN_MAD='bridge']"
|
||||
|
||||
hm = VNMMAD::VNMDriver.from_base64(template64)
|
||||
hm = VNMMAD::VNMDriver.from_base64(template64, xpath_filter)
|
||||
|
||||
hm.activate_vf(hm.vm)
|
||||
|
||||
|
@ -24,15 +24,15 @@ require 'vnmmad'
|
||||
template64 = STDIN.read
|
||||
deploy_id = ARGV[0]
|
||||
vn_id = Integer(ARGV[1])
|
||||
xpath_filter = "TEMPLATE/NIC[VN_MAD='fw']"
|
||||
xpath_filter = "TEMPLATE/NIC[VN_MAD='bridge']"
|
||||
|
||||
begin
|
||||
# PRE - Related changes
|
||||
hm = VNMMAD::NoVLANDriver.from_base64(template64, xpath_filter, deploy_id)
|
||||
hm.update(vn_id)
|
||||
|
||||
# TODO: Implement update for vf
|
||||
# filter_driver.activate_vf(filter_driver.vm)
|
||||
#VF - Related changes
|
||||
hm.update_vf(hm.vm, vn_id)
|
||||
rescue StandardError => e
|
||||
OpenNebula.log_error(e.message)
|
||||
OpenNebula.log_error(e.backtrace)
|
||||
|
@ -37,8 +37,8 @@ begin
|
||||
deploy_id)
|
||||
filter_driver.update(vn_id)
|
||||
|
||||
# TODO: Implement update for vf
|
||||
# filter_driver.activate_vf(filter_driver.vm)
|
||||
# VF - Related changes
|
||||
filter_driver.update_vf(filter_driver.vm, vn_id)
|
||||
rescue StandardError => e
|
||||
OpenNebula.log_error(e.message)
|
||||
OpenNebula.log_error(e.backtrace)
|
||||
|
@ -19,6 +19,12 @@
|
||||
# Module to use as mixin for configuring VFs
|
||||
###########################################################################
|
||||
module VNMMAD::VirtualFunction
|
||||
# Attributes that can be updated on update_nic action
|
||||
SUPPORTED_UPDATE = [
|
||||
:vlan_id,
|
||||
:spoofchk,
|
||||
:trust
|
||||
]
|
||||
|
||||
# This function iterates for each VF defined as a PCI device in the VM
|
||||
# and sets the MAC and VLAN through the ip link command
|
||||
@ -66,11 +72,7 @@ module VNMMAD::VirtualFunction
|
||||
next if pci[:short_address].nil?
|
||||
next if is_attach && pci[:attach] != 'YES'
|
||||
|
||||
# Look for the associated PF
|
||||
cmd = "find /sys/devices -type l -name 'virtfn*' -printf '%p#'"\
|
||||
" -exec readlink -f '{}' \\;"
|
||||
|
||||
out, _err, _rc = Open3.capture3(cmd)
|
||||
out = find_vfs
|
||||
|
||||
next if out.nil? || out.empty?
|
||||
|
||||
@ -79,29 +81,12 @@ module VNMMAD::VirtualFunction
|
||||
out.each_line do |line|
|
||||
next unless line.match(regexp)
|
||||
|
||||
virtfn, _vf = line.split('#')
|
||||
pf_dev, vf = find_pf_dev(line)
|
||||
|
||||
# rubocop:disable Layout/LineLength
|
||||
# Matched line is in the form:
|
||||
# virtfn /sys/devices/pci0000:80/0000:80:03.2/0000:85:00.0/virtfn3
|
||||
# _vf /sys/devices/pci0000:80/0000:80:03.2/0000:85:02.3
|
||||
# rubocop:enable Layout/LineLength
|
||||
m = virtfn.match(/virtfn([0-9]+)/)
|
||||
next if pf_dev.nil?
|
||||
|
||||
next if m.nil?
|
||||
|
||||
cmd = "ls #{File.dirname(virtfn)}/net"
|
||||
pf_dev, _err, _rc = Open3.capture3(cmd)
|
||||
|
||||
next if pf_dev.nil? || pf_dev.empty?
|
||||
|
||||
pf_dev.strip!
|
||||
|
||||
cmd = "#{command(:ip)} link set #{pf_dev} vf #{m[1]}"
|
||||
cmd << " mac #{pci[:mac]}" if pci[:mac]
|
||||
cmd << " vlan #{pci[:vlan_id]}" if pci[:vlan_id]
|
||||
cmd << " spoofchk #{on_off(pci[:spoofchk])}" if pci[:spoofchk]
|
||||
cmd << " trust #{on_off(pci[:trust])}" if pci[:trust]
|
||||
cmd = "#{command(:ip)} link set #{pf_dev} vf #{vf}"
|
||||
cmd << set_ip_links(pci)
|
||||
|
||||
OpenNebula.exec_and_log(cmd)
|
||||
end
|
||||
@ -109,6 +94,42 @@ module VNMMAD::VirtualFunction
|
||||
# rubocop:enable Style/CombinableLoops
|
||||
end
|
||||
|
||||
def update_vf(vm, vnet_id)
|
||||
changes = vm.changes.select do |k, _|
|
||||
SUPPORTED_UPDATE.include?(k)
|
||||
end
|
||||
|
||||
return 0 if changes.empty?
|
||||
|
||||
vm.each_pci do |pci|
|
||||
next unless Integer(pci[:network_id]) == vnet_id
|
||||
|
||||
out = find_vfs
|
||||
|
||||
next if out.nil? || out.empty?
|
||||
|
||||
regexp = Regexp.new("#{pci[:short_address]}$")
|
||||
|
||||
out.each_line do |line|
|
||||
next unless line.match(regexp)
|
||||
|
||||
pf_dev, vf = find_pf_dev(line)
|
||||
|
||||
next if pf_dev.nil?
|
||||
|
||||
cmd = "#{command(:ip)} link set #{pf_dev} vf #{vf}"
|
||||
cmd << set_ip_links(pci)
|
||||
|
||||
OpenNebula.exec_and_log(cmd)
|
||||
end
|
||||
end
|
||||
|
||||
0
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Set on/off string (ip command) based on OpenNebula (YES/NO) setting
|
||||
def on_off(option)
|
||||
if option.match(/^yes$|^on$/i)
|
||||
'on'
|
||||
@ -117,5 +138,58 @@ module VNMMAD::VirtualFunction
|
||||
end
|
||||
end
|
||||
|
||||
# Look for the associated VFs defined in the host
|
||||
# @return [String] lines with virtfn sys entries and their associated sys dev
|
||||
def find_vfs
|
||||
cmd = "find /sys/devices -type l -name 'virtfn*' -printf '%p#'"\
|
||||
" -exec readlink -f '{}' \\;"
|
||||
|
||||
out, _err, _rc = Open3.capture3(cmd)
|
||||
|
||||
out
|
||||
end
|
||||
|
||||
# Look for the associated PF device to use it as argument for ip command
|
||||
#
|
||||
# @return [string, string] the PF device and associated VF number
|
||||
#
|
||||
# Matched line (argument) is in the form:
|
||||
# virtfn /sys/devices/pci0000:80/0000:80:03.2/0000:85:00.0/virtfn3
|
||||
# _vf /sys/devices/pci0000:80/0000:80:03.2/0000:85:02.3
|
||||
def find_pf_dev(line)
|
||||
virtfn, _vf = line.split('#')
|
||||
|
||||
m = virtfn.match(/virtfn([0-9]+)/)
|
||||
|
||||
return nil, nil if m.nil?
|
||||
|
||||
pf_dev, _err, _rc = Open3.capture3("ls #{File.dirname(virtfn)}/net")
|
||||
|
||||
return nil, nil if pf_dev.nil? || pf_dev.empty?
|
||||
|
||||
pf_dev.strip!
|
||||
|
||||
return pf_dev, m[1]
|
||||
end
|
||||
|
||||
# Generate ip link attributes for the VF
|
||||
def set_ip_links(pci)
|
||||
cmd = ""
|
||||
|
||||
# if no vlan id is set use 0 to reset it
|
||||
vlan_id = if pci[:vlan_id]
|
||||
pci[:vlan_id]
|
||||
else
|
||||
0
|
||||
end
|
||||
|
||||
cmd << " vlan #{vlan_id}"
|
||||
cmd << " mac #{pci[:mac]}" if pci[:mac]
|
||||
cmd << " spoofchk #{on_off(pci[:spoofchk])}" if pci[:spoofchk]
|
||||
cmd << " trust #{on_off(pci[:trust])}" if pci[:trust]
|
||||
|
||||
cmd
|
||||
end
|
||||
|
||||
end
|
||||
# rubocop:enable Style/ClassAndModuleChildren
|
||||
|
@ -31,8 +31,8 @@ begin
|
||||
ovs = OpenvSwitchVLAN.from_base64(template64, xpath_filter, deploy_id)
|
||||
ovs.update(vn_id)
|
||||
|
||||
# TODO: Implement update for vf
|
||||
# filter_driver.activate_vf(filter_driver.vm)
|
||||
# VF - Related changes
|
||||
ovs.update_vf(ovs.vm, vn_id)
|
||||
rescue StandardError => e
|
||||
OpenNebula.log_error(e.message)
|
||||
OpenNebula.log_error(e.backtrace)
|
||||
|
Loading…
x
Reference in New Issue
Block a user