Configure the numvfs for SRIOV interfaces

This patch shall create VFs via the PCI SYS interface.
Default value : $::os_service_default
Sample Format : ['eth0:4','eth2:128']
For values as in sample format, the sriov_numvfs config files
for eth0 and eth2 will have the values 4 and 128 respectively
The SR-IOV numvfs configuration shall be persisted in /sbin/ifup-local
so that, during the bootup of the compute nodes, the numvfs
configuration will be restored.

Change-Id: I7450b904475bdf46498d9af633416b3eba12f761
Implements: blueprint tripleo-sriov
Signed-off-by: karthik s <ksundara@redhat.com>
This commit is contained in:
karthik s 2016-08-26 21:48:04 +05:30
parent 6a6aeaa953
commit eec3bba44b
10 changed files with 320 additions and 0 deletions

View File

@ -0,0 +1,57 @@
Puppet::Type.type(:sriov_vf_config).provide(:numvfs) do
desc <<-EOT
The file /sys/class/net/<sriov_interface_name>/device/sriov_numvfs will be
present when a physical PCIe device supports SR-IOV. A number written to
this file will enable the specified number of VFs. This provider shall read
the file and ensure that the value is zero, before writing the number of
VFs that should be enabled. If the VFs needs to be disabled then we shall
write a zero to this file.
EOT
def create
if File.file?(sriov_numvfs_path)
_set_numvfs
else
fail("#{sriov_numvfs_path} doesn't exist. Check if #{sriov_get_interface} is a valid network interface supporting SR-IOV")
end
end
def destroy
if File.file?(sriov_numvfs_path)
File.write(sriov_numvfs_path,"0")
end
end
def exists?
if File.file?(sriov_numvfs_path)
cur_value = File.read(sriov_numvfs_path)
if cur_value.to_i == sriov_numvfs_value
return true
end
end
return false
end
def _set_numvfs
# During an update, the content of file sriov_numvfs_path has to be set
# to 0 (ZERO), before writing the actual value
cur_value = File.read(sriov_numvfs_path)
if cur_value != 0
File.write(sriov_numvfs_path,"0")
end
File.write(sriov_numvfs_path,sriov_numvfs_value)
end
def sriov_numvfs_path
"/sys/class/net/#{sriov_get_interface}/device/sriov_numvfs"
end
def sriov_get_interface
resource[:name].split(':', 2).first
end
def sriov_numvfs_value
resource[:name].split(':', 2).last.to_i
end
end

View File

@ -0,0 +1,10 @@
Puppet::Type.newtype(:sriov_vf_config) do
ensurable
newparam(:name) do
desc "sriov_numvfs conf as <physical_network>:<number_of_vfs> format"
newvalues(/^[a-z0-9\-_]+:[0-9]+$/)
end
end

27
manifests/host/sriov.pp Normal file
View File

@ -0,0 +1,27 @@
# == Class: tripleo::host::sriov
#
# Configures host configuration for the SR-IOV interfaces
#
# === Parameters
#
# [*number_of_vfs*]
# (optional) List of <physical_network>:<number_of_vfs> specifying the number
# VFs to be exposed per physical interface.
# For example, to configure two interface with number of VFs, specify
# it as ['eth1:4','eth2:10']
# Defaults to []
#
class tripleo::host::sriov (
$number_of_vfs = [],
) {
if !empty($number_of_vfs) {
sriov_vf_config { $number_of_vfs: ensure => present }
# the numvfs configuration needs to be persisted for every boot
tripleo::host::sriov::numvfs_persistence {'persistent_numvfs':
vf_defs => $number_of_vfs,
content_string => "#!/bin/bash\n"
}
}
}

View File

@ -0,0 +1,55 @@
#
# tripleo::host::sriov::numvfs_persistence used by tripleo::host::sriov
#
# === Parameters:
#
# [*vf_defs*]
# (required) Array of of <physical_interface>:<numvfs>.
# Example: ['eth1:10','eth2:8']
#
# [*content_string*]
# (required) String which shall be written to the script file.
#
define tripleo::host::sriov::numvfs_persistence(
$vf_defs,
$content_string
){
# Since reduce isn't available, we use recursion to iterate each entries of
# "physical_interface:vfs" and accumulate the content that needs to be
# written to the script file.
include ::stdlib
if empty($vf_defs) {
file { '/etc/sysconfig/allocate_vfs':
ensure => file,
content => $content_string,
group => 'root',
mode => '0755',
owner => 'root',
}
file { '/sbin/ifup-local':
group => 'root',
mode => '0755',
owner => 'root',
content => '#!/bin/bash',
replace => false
}
file_line { 'call_ifup-local':
path => '/sbin/ifup-local',
line => '/etc/sysconfig/allocate_vfs $1',
require => File['/sbin/ifup-local'],
}
} else {
$vfspec = split($vf_defs[0], ':')
$interface = $vfspec[0]
$count = $vfspec[1]
$vfdef_str = "${content_string}[ \"${interface}\" == \"\$1\" ] && echo ${count} > /sys/class/net/${interface}/device/sriov_numvfs\n"
tripleo::host::sriov::numvfs_persistence{"mapped ${interface}":
vf_defs => delete_at($vf_defs, 0),
content_string => $vfdef_str
}
}
}

View File

@ -36,6 +36,7 @@ class tripleo::profile::base::neutron::sriov(
if $step >= 4 {
if 'sriovnicswitch' in $mechanism_drivers {
include ::neutron::agents::ml2::sriov
include ::tripleo::host::sriov
}
}

View File

@ -0,0 +1,4 @@
---
features:
- Added a provider to configure VFs for SR-IOV interface.
Added a define for persistence of the VFs configuratin.

View File

@ -0,0 +1,39 @@
require 'spec_helper'
describe 'tripleo::host::sriov' do
shared_examples_for 'sriov vfs configuration for Red Hat distributions' do
let :facts do
{
:osfamily => 'RedHat',
:operatingsystemmajrelease => 7,
}
end
let :params do
{:number_of_vfs => []}
end
it 'does not configure numvfs by default' do
is_expected.not_to contain_sriov_vf_config([])
end
context 'when number_of_vfs is configured' do
let :params do
{:number_of_vfs => ['eth0:4','eth1:5']}
end
it 'configures numvfs' do
is_expected.to contain_sriov_vf_config('eth0:4').with( :ensure => 'present' )
is_expected.to contain_sriov_vf_config('eth1:5').with( :ensure => 'present')
is_expected.to contain_tripleo__host__sriov__numvfs_persistence('persistent_numvfs').with(
:vf_defs => ['eth0:4','eth1:5'],
:content_string => "#!/bin/bash\n"
)
end
end
end
it_configures 'sriov vfs configuration for Red Hat distributions'
end

View File

@ -0,0 +1,40 @@
require 'spec_helper'
describe 'tripleo::host::sriov::numvfs_persistence' do
describe 'confugure numvfs for persistence' do
let :title do
'numvfs'
end
let :params do
{
:name => 'persistence',
:vf_defs => ['eth0:10','eth1:8'],
:content_string => "Hashbang\n"
}
end
it 'configures persistence' do
is_expected.to contain_file('/etc/sysconfig/allocate_vfs').with(
:ensure => 'file',
:content => "Hashbang\n[ \"eth0\" == \"\$1\" ] && echo 10 > /sys/class/net/eth0/device/sriov_numvfs\n[ \"eth1\" == \"\$1\" ] && echo 8 > /sys/class/net/eth1/device/sriov_numvfs\n",
:group => 'root',
:mode => '0755',
:owner => 'root',
)
is_expected.to contain_file('/sbin/ifup-local').with(
:group => 'root',
:mode => '0755',
:owner => 'root',
:content => '#!/bin/bash',
:replace => false,
)
is_expected.to contain_file_line('call_ifup-local').with(
:path => '/sbin/ifup-local',
:line => '/etc/sysconfig/allocate_vfs $1',
)
end
end
end

View File

@ -0,0 +1,40 @@
require 'puppet'
require 'spec_helper'
require 'puppet/provider/sriov_vf_config/numvfs'
provider_class = Puppet::Type.type(:sriov_vf_config).
provider(:numvfs)
describe provider_class do
let(:test_cfg_path) { "/tmp/test-ifup-local.txt" }
let :numvfs_conf do
{
:name => 'eth0:10',
:ensure => 'present',
}
end
describe 'when setting the attributes' do
let :resource do
Puppet::Type::Sriov_vf_config.new(numvfs_conf)
end
let :provider do
provider_class.new(resource)
end
it 'should return the correct interface name' do
expect(provider.sriov_get_interface).to eql('eth0')
end
it 'should return the correct numvfs value' do
expect(provider.sriov_numvfs_value).to eql(10)
end
it 'should return path of the file to enable vfs' do
expect(provider.sriov_numvfs_path).to eql('/sys/class/net/eth0/device/sriov_numvfs')
end
end
end

View File

@ -0,0 +1,47 @@
require 'puppet'
require 'puppet/type/sriov_vf_config'
describe 'Puppet::Type.type(:sriov_vf_config)' do
it 'should allow name to be passed' do
expect{Puppet::Type.type(:sriov_vf_config).new(
:name => 'eth0:10',
:ensure => 'present'
)}.not_to raise_error
end
it 'should allow name to be passed with -' do
expect{Puppet::Type.type(:sriov_vf_config).new(
:name => 'eth-0:10',
:ensure => 'present'
)}.not_to raise_error
end
it 'should allow name to be passed with _' do
expect{Puppet::Type.type(:sriov_vf_config).new(
:name => 'eth_0:10',
:ensure => 'present'
)}.not_to raise_error
end
it 'should throw error for invalid format' do
expect{Puppet::Type.type(:sriov_vf_config).new(
:name => 'eth0',
:ensure => 'present'
)}.to raise_error(Puppet::ResourceError)
end
it 'should throw error for invalid format without interface name' do
expect{Puppet::Type.type(:sriov_vf_config).new(
:name => ':9',
:ensure => 'present'
)}.to raise_error(Puppet::ResourceError)
end
it 'should throw error for invalid format for numvfs' do
expect{Puppet::Type.type(:sriov_vf_config).new(
:name => 'eth8:none',
:ensure => 'present'
)}.to raise_error(Puppet::ResourceError)
end
it 'should throw error for invalid format without numvfs' do
expect{Puppet::Type.type(:sriov_vf_config).new(
:name => 'eth0:',
:ensure => 'present'
)}.to raise_error(Puppet::ResourceError)
end
end