1
0
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:
Ruben S. Montero 2023-07-31 15:24:34 +02:00
parent 00549961bc
commit d6895c4716
No known key found for this signature in database
GPG Key ID: A0CEA6FA880A1D87
8 changed files with 117 additions and 39 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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