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")
class IpCommandOperationNotSupportedError(SriovNicError):
message = _("Operation not supported on device %(dev_name)s")
class InvalidPciSlotError(SriovNicError):
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_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

View File

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

View File

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

View File

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