Merge "sriov: update port state even if ip link fails"

This commit is contained in:
Jenkins 2015-09-09 18:16:31 +00:00 committed by Gerrit Code Review
commit d8cfee987d
5 changed files with 72 additions and 24 deletions

View File

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

View File

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

View File

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

View File

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

View File

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