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")
|
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):
|
class InvalidPciSlotError(SriovNicError):
|
||||||
message = _("Invalid pci slot %(pci_slot)s")
|
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_LINE_FORMAT = VF_PATTERN + MAC_PATTERN + ANY_PATTERN + STATE_PATTERN
|
||||||
VF_DETAILS_REG_EX = re.compile(VF_LINE_FORMAT)
|
VF_DETAILS_REG_EX = re.compile(VF_LINE_FORMAT)
|
||||||
|
|
||||||
|
IP_LINK_OP_NOT_SUPPORTED = 'RTNETLINK answers: Operation not supported'
|
||||||
|
|
||||||
class LinkState(object):
|
class LinkState(object):
|
||||||
ENABLE = "enable"
|
ENABLE = "enable"
|
||||||
DISABLE = "disable"
|
DISABLE = "disable"
|
||||||
@ -46,6 +48,29 @@ class PciDeviceIPWrapper(ip_lib.IPWrapper):
|
|||||||
super(PciDeviceIPWrapper, self).__init__()
|
super(PciDeviceIPWrapper, self).__init__()
|
||||||
self.dev_name = dev_name
|
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):
|
def get_assigned_macs(self, vf_list):
|
||||||
"""Get assigned mac addresses for 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 \
|
status_str = self.LinkState.ENABLE if state else \
|
||||||
self.LinkState.DISABLE
|
self.LinkState.DISABLE
|
||||||
|
self._set_feature(vf_index, "state", status_str)
|
||||||
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)
|
|
||||||
|
|
||||||
def set_vf_spoofcheck(self, vf_index, enabled):
|
def set_vf_spoofcheck(self, vf_index, enabled):
|
||||||
"""sets vf spoofcheck
|
"""sets vf spoofcheck
|
||||||
@ -116,13 +134,7 @@ class PciDeviceIPWrapper(ip_lib.IPWrapper):
|
|||||||
False to disable
|
False to disable
|
||||||
"""
|
"""
|
||||||
setting = "on" if enabled else "off"
|
setting = "on" if enabled else "off"
|
||||||
|
self._set_feature(vf_index, "spoofchk", setting)
|
||||||
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))
|
|
||||||
|
|
||||||
def set_vf_max_rate(self, vf_index, max_tx_rate):
|
def set_vf_max_rate(self, vf_index, max_tx_rate):
|
||||||
"""sets vf max rate.
|
"""sets vf max rate.
|
||||||
@ -130,14 +142,7 @@ class PciDeviceIPWrapper(ip_lib.IPWrapper):
|
|||||||
@param vf_index: vf index
|
@param vf_index: vf index
|
||||||
@param max_tx_rate: vf max tx rate in Mbps
|
@param max_tx_rate: vf max tx rate in Mbps
|
||||||
"""
|
"""
|
||||||
try:
|
self._set_feature(vf_index, "rate", str(max_tx_rate))
|
||||||
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)
|
|
||||||
|
|
||||||
def _get_vf_link_show(self, vf_list, link_show_out):
|
def _get_vf_link_show(self, vf_list, link_show_out):
|
||||||
"""Get link show output for VFs
|
"""Get link show output for VFs
|
||||||
|
@ -210,8 +210,11 @@ class SriovNicSwitchAgent(object):
|
|||||||
try:
|
try:
|
||||||
self.eswitch_mgr.set_device_state(device, pci_slot,
|
self.eswitch_mgr.set_device_state(device, pci_slot,
|
||||||
admin_state_up)
|
admin_state_up)
|
||||||
|
except exc.IpCommandOperationNotSupportedError:
|
||||||
|
LOG.warning(_LW("Device %s does not support state change"),
|
||||||
|
device)
|
||||||
except exc.SriovNicError:
|
except exc.SriovNicError:
|
||||||
LOG.exception(_LE("Failed to set device %s state"), device)
|
LOG.warning(_LW("Failed to set device %s state"), device)
|
||||||
return
|
return
|
||||||
if admin_state_up:
|
if admin_state_up:
|
||||||
# update plugin about port status
|
# update plugin about port status
|
||||||
|
@ -132,3 +132,13 @@ class TestPciLib(base.BaseTestCase):
|
|||||||
self.pci_wrapper.set_vf_max_rate,
|
self.pci_wrapper.set_vf_max_rate,
|
||||||
self.VF_INDEX,
|
self.VF_INDEX,
|
||||||
1000)
|
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 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 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.plugins.ml2.drivers.mech_sriov.agent import sriov_nic_agent
|
||||||
from neutron.tests import base
|
from neutron.tests import base
|
||||||
|
|
||||||
@ -220,6 +221,31 @@ class TestSriovAgent(base.BaseTestCase):
|
|||||||
False)
|
False)
|
||||||
self.assertTrue(agent.plugin_rpc.update_device_up.called)
|
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):
|
def test_treat_devices_added_updated_admin_state_up_false(self):
|
||||||
agent = self.agent
|
agent = self.agent
|
||||||
mock_details = {'device': 'aa:bb:cc:dd:ee:ff',
|
mock_details = {'device': 'aa:bb:cc:dd:ee:ff',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user