Merge "sriov: update port state even if ip link fails"
This commit is contained in:
commit
d8cfee987d
@ -28,5 +28,9 @@ class IpCommandError(SriovNicError):
|
||||
message = _("ip command failed on device %(dev_name)s: %(reason)s")
|
||||
|
||||
|
||||
class IpCommandOperationNotSupportedError(SriovNicError):
|
||||
message = _("Operation not supported on device %(dev_name)s")
|
||||
|
||||
|
||||
class InvalidPciSlotError(SriovNicError):
|
||||
message = _("Invalid pci slot %(pci_slot)s")
|
||||
|
@ -38,6 +38,8 @@ class PciDeviceIPWrapper(ip_lib.IPWrapper):
|
||||
VF_LINE_FORMAT = VF_PATTERN + MAC_PATTERN + ANY_PATTERN + STATE_PATTERN
|
||||
VF_DETAILS_REG_EX = re.compile(VF_LINE_FORMAT)
|
||||
|
||||
IP_LINK_OP_NOT_SUPPORTED = 'RTNETLINK answers: Operation not supported'
|
||||
|
||||
class LinkState(object):
|
||||
ENABLE = "enable"
|
||||
DISABLE = "disable"
|
||||
@ -46,6 +48,29 @@ class PciDeviceIPWrapper(ip_lib.IPWrapper):
|
||||
super(PciDeviceIPWrapper, self).__init__()
|
||||
self.dev_name = dev_name
|
||||
|
||||
def _set_feature(self, vf_index, feature, value):
|
||||
"""Sets vf feature
|
||||
|
||||
Checks if the feature is not supported or there's some
|
||||
general error during ip link invocation and raises
|
||||
exception accordingly.
|
||||
|
||||
:param vf_index: vf index
|
||||
:param feature: name of a feature to be passed to ip link,
|
||||
such as 'state' or 'spoofchk'
|
||||
:param value: value of the feature setting
|
||||
"""
|
||||
try:
|
||||
self._as_root([], "link", ("set", self.dev_name, "vf",
|
||||
str(vf_index), feature, value))
|
||||
except Exception as e:
|
||||
if self.IP_LINK_OP_NOT_SUPPORTED in str(e):
|
||||
raise exc.IpCommandOperationNotSupportedError(
|
||||
dev_name=self.dev_name)
|
||||
else:
|
||||
raise exc.IpCommandError(dev_name=self.dev_name,
|
||||
reason=str(e))
|
||||
|
||||
def get_assigned_macs(self, vf_list):
|
||||
"""Get assigned mac addresses for vf list.
|
||||
|
||||
@ -99,14 +124,7 @@ class PciDeviceIPWrapper(ip_lib.IPWrapper):
|
||||
"""
|
||||
status_str = self.LinkState.ENABLE if state else \
|
||||
self.LinkState.DISABLE
|
||||
|
||||
try:
|
||||
self._as_root([], "link", ("set", self.dev_name, "vf",
|
||||
str(vf_index), "state", status_str))
|
||||
except Exception as e:
|
||||
LOG.exception(_LE("Failed executing ip command"))
|
||||
raise exc.IpCommandError(dev_name=self.dev_name,
|
||||
reason=e)
|
||||
self._set_feature(vf_index, "state", status_str)
|
||||
|
||||
def set_vf_spoofcheck(self, vf_index, enabled):
|
||||
"""sets vf spoofcheck
|
||||
@ -116,13 +134,7 @@ class PciDeviceIPWrapper(ip_lib.IPWrapper):
|
||||
False to disable
|
||||
"""
|
||||
setting = "on" if enabled else "off"
|
||||
|
||||
try:
|
||||
self._as_root('', "link", ("set", self.dev_name, "vf",
|
||||
str(vf_index), "spoofchk", setting))
|
||||
except Exception as e:
|
||||
raise exc.IpCommandError(dev_name=self.dev_name,
|
||||
reason=str(e))
|
||||
self._set_feature(vf_index, "spoofchk", setting)
|
||||
|
||||
def set_vf_max_rate(self, vf_index, max_tx_rate):
|
||||
"""sets vf max rate.
|
||||
@ -130,14 +142,7 @@ class PciDeviceIPWrapper(ip_lib.IPWrapper):
|
||||
@param vf_index: vf index
|
||||
@param max_tx_rate: vf max tx rate in Mbps
|
||||
"""
|
||||
try:
|
||||
self._as_root([], "link", ("set", self.dev_name, "vf",
|
||||
str(vf_index), "rate",
|
||||
str(max_tx_rate)))
|
||||
except Exception as e:
|
||||
LOG.exception(_LE("Failed executing ip command"))
|
||||
raise exc.IpCommandError(dev_name=self.dev_name,
|
||||
reason=e)
|
||||
self._set_feature(vf_index, "rate", str(max_tx_rate))
|
||||
|
||||
def _get_vf_link_show(self, vf_list, link_show_out):
|
||||
"""Get link show output for VFs
|
||||
|
@ -210,8 +210,11 @@ class SriovNicSwitchAgent(object):
|
||||
try:
|
||||
self.eswitch_mgr.set_device_state(device, pci_slot,
|
||||
admin_state_up)
|
||||
except exc.IpCommandOperationNotSupportedError:
|
||||
LOG.warning(_LW("Device %s does not support state change"),
|
||||
device)
|
||||
except exc.SriovNicError:
|
||||
LOG.exception(_LE("Failed to set device %s state"), device)
|
||||
LOG.warning(_LW("Failed to set device %s state"), device)
|
||||
return
|
||||
if admin_state_up:
|
||||
# update plugin about port status
|
||||
|
@ -132,3 +132,13 @@ class TestPciLib(base.BaseTestCase):
|
||||
self.pci_wrapper.set_vf_max_rate,
|
||||
self.VF_INDEX,
|
||||
1000)
|
||||
|
||||
def test_set_vf_state_not_supported(self):
|
||||
with mock.patch.object(self.pci_wrapper,
|
||||
"_execute") as mock_exec:
|
||||
mock_exec.side_effect = Exception(
|
||||
pci_lib.PciDeviceIPWrapper.IP_LINK_OP_NOT_SUPPORTED)
|
||||
self.assertRaises(exc.IpCommandOperationNotSupportedError,
|
||||
self.pci_wrapper.set_vf_state,
|
||||
self.VF_INDEX,
|
||||
state=True)
|
||||
|
@ -19,6 +19,7 @@ from oslo_config import cfg
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from neutron.plugins.ml2.drivers.mech_sriov.agent.common import config # noqa
|
||||
from neutron.plugins.ml2.drivers.mech_sriov.agent.common import exceptions
|
||||
from neutron.plugins.ml2.drivers.mech_sriov.agent import sriov_nic_agent
|
||||
from neutron.tests import base
|
||||
|
||||
@ -220,6 +221,31 @@ class TestSriovAgent(base.BaseTestCase):
|
||||
False)
|
||||
self.assertTrue(agent.plugin_rpc.update_device_up.called)
|
||||
|
||||
def test_treat_device_ip_link_state_not_supported(self):
|
||||
agent = self.agent
|
||||
agent.plugin_rpc = mock.Mock()
|
||||
agent.eswitch_mgr = mock.Mock()
|
||||
agent.eswitch_mgr.device_exists.return_value = True
|
||||
agent.eswitch_mgr.set_device_state.side_effect = (
|
||||
exceptions.IpCommandOperationNotSupportedError(
|
||||
dev_name='aa:bb:cc:dd:ee:ff'))
|
||||
|
||||
agent.treat_device('aa:bb:cc:dd:ee:ff', '1:2:3:0',
|
||||
admin_state_up=True)
|
||||
self.assertTrue(agent.plugin_rpc.update_device_up.called)
|
||||
|
||||
def test_treat_device_set_device_state_exception(self):
|
||||
agent = self.agent
|
||||
agent.plugin_rpc = mock.Mock()
|
||||
agent.eswitch_mgr = mock.Mock()
|
||||
agent.eswitch_mgr.device_exists.return_value = True
|
||||
agent.eswitch_mgr.set_device_state.side_effect = (
|
||||
exceptions.SriovNicError())
|
||||
|
||||
agent.treat_device('aa:bb:cc:dd:ee:ff', '1:2:3:0',
|
||||
admin_state_up=True)
|
||||
self.assertFalse(agent.plugin_rpc.update_device_up.called)
|
||||
|
||||
def test_treat_devices_added_updated_admin_state_up_false(self):
|
||||
agent = self.agent
|
||||
mock_details = {'device': 'aa:bb:cc:dd:ee:ff',
|
||||
|
Loading…
Reference in New Issue
Block a user