From 687fd6b7318ee34f8e06cf5c05feac1a3e4e494a Mon Sep 17 00:00:00 2001 From: Miguel Lavalle Date: Wed, 4 May 2016 00:09:09 +0000 Subject: [PATCH] SR-IOV driver and SimpleAgentMechanismDriverBase Since commit 83c9578fcc5d06b634d48e0e186bebd60a60322e was merged, the SR-IOV mechanism driver requires an agent in the compute nodes. This change makes the SR-IOV mechanism driver to inherit from SimpleAgentMechanismDriverBase, like all the other agent based ML2 drivers Change-Id: Icffc097a42dd71546b97bb7b43edd1e205c9dd15 Closes-Bug: #1578274 --- .../mech_sriov/mech_driver/mech_driver.py | 68 +++++++++---------- .../mech_driver/test_mech_sriov_nic_switch.py | 8 +-- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/neutron/plugins/ml2/drivers/mech_sriov/mech_driver/mech_driver.py b/neutron/plugins/ml2/drivers/mech_sriov/mech_driver/mech_driver.py index 8de1d5c5a34..651cf1333c5 100644 --- a/neutron/plugins/ml2/drivers/mech_sriov/mech_driver/mech_driver.py +++ b/neutron/plugins/ml2/drivers/mech_sriov/mech_driver/mech_driver.py @@ -21,6 +21,7 @@ from neutron._i18n import _, _LE, _LW from neutron.extensions import portbindings from neutron.plugins.common import constants as p_const from neutron.plugins.ml2 import driver_api as api +from neutron.plugins.ml2.drivers import mech_agent from neutron.plugins.ml2.drivers.mech_sriov.mech_driver \ import exceptions as exc from neutron.services.qos import qos_consts @@ -43,7 +44,7 @@ sriov_opts = [ cfg.CONF.register_opts(sriov_opts, "ml2_sriov") -class SriovNicSwitchMechanismDriver(api.MechanismDriver): +class SriovNicSwitchMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase): """Mechanism Driver for SR-IOV capable NIC based switching. The SriovNicSwitchMechanismDriver integrates the ml2 plugin with the @@ -81,7 +82,12 @@ class SriovNicSwitchMechanismDriver(api.MechanismDriver): else VIF_TYPE_HW_VEB for vtype in self.supported_vnic_types}) self.vif_details = vif_details - self.supported_network_types = (p_const.TYPE_VLAN, p_const.TYPE_FLAT) + + def get_allowed_network_types(self, agent): + return (p_const.TYPE_FLAT, p_const.TYPE_VLAN) + + def get_mappings(self, agent): + return agent['configurations'].get('device_mappings', {}) def initialize(self): try: @@ -103,9 +109,6 @@ class SriovNicSwitchMechanismDriver(api.MechanismDriver): vnic_type) return - vif_type = self.vnic_type_for_vif_type.get(vnic_type, - VIF_TYPE_HW_VEB) - if not self._check_supported_pci_vendor_device(context): LOG.debug("Refusing to bind due to unsupported pci_vendor device") return @@ -118,43 +121,40 @@ class SriovNicSwitchMechanismDriver(api.MechanismDriver): # either. This should be changed in the future so physical # functions can use device mapping checks and the plugin can # get port status updates. - self.try_to_bind(context, None, vif_type) + for segment in context.segments_to_bind: + if self.try_to_bind_segment_for_agent(context, segment, + agent=None): + break return for agent in context.host_agents(self.agent_type): LOG.debug("Checking agent: %s", agent) if agent['alive']: - if self.try_to_bind(context, agent, vif_type): - return + for segment in context.segments_to_bind: + if self.try_to_bind_segment_for_agent(context, segment, + agent): + return else: LOG.warning(_LW("Attempting to bind with dead agent: %s"), agent) - def try_to_bind(self, context, agent, vif_type): - for segment in context.segments_to_bind: - if self.check_segment(segment, agent): - port_status = (constants.PORT_STATUS_ACTIVE if agent is None - else constants.PORT_STATUS_DOWN) - context.set_binding(segment[api.ID], - vif_type, - self._get_vif_details(segment), - port_status) - LOG.debug("Bound using segment: %s", segment) - return True - return False + def try_to_bind_segment_for_agent(self, context, segment, agent): + vnic_type = context.current.get(portbindings.VNIC_TYPE, + portbindings.VNIC_DIRECT) + vif_type = self.vnic_type_for_vif_type.get(vnic_type, + VIF_TYPE_HW_VEB) + if not self.check_segment_for_agent(segment, agent): + return False + port_status = (constants.PORT_STATUS_ACTIVE if agent is None + else constants.PORT_STATUS_DOWN) + context.set_binding(segment[api.ID], + vif_type, + self._get_vif_details(segment), + port_status) + LOG.debug("Bound using segment: %s", segment) + return True - def filter_hosts_with_segment_access( - self, context, segments, candidate_hosts, agent_getter): - - hosts = set() - filters = {'host': candidate_hosts, 'agent_type': [self.agent_type]} - for agent in agent_getter(context, filters=filters): - if any(self.check_segment(s, agent) for s in segments): - hosts.add(agent['host']) - - return hosts - - def check_segment(self, segment, agent=None): + def check_segment_for_agent(self, segment, agent=None): """Check if segment can be bound. :param segment: segment dictionary describing segment to bind @@ -162,9 +162,9 @@ class SriovNicSwitchMechanismDriver(api.MechanismDriver): :returns: True if segment can be bound for agent """ network_type = segment[api.NETWORK_TYPE] - if network_type in self.supported_network_types: + if network_type in self.get_allowed_network_types(agent): if agent: - mappings = agent['configurations'].get('device_mappings', {}) + mappings = self.get_mappings(agent) LOG.debug("Checking segment: %(segment)s " "for mappings: %(mappings)s ", {'segment': segment, 'mappings': mappings}) diff --git a/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/mech_driver/test_mech_sriov_nic_switch.py b/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/mech_driver/test_mech_sriov_nic_switch.py index b47ce85555f..4c7c4973cbc 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/mech_driver/test_mech_sriov_nic_switch.py +++ b/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/mech_driver/test_mech_sriov_nic_switch.py @@ -91,15 +91,15 @@ class SriovSwitchMechGenericTestCase(SriovNicSwitchMechanismBaseTestCase, """Validate the check_segment call.""" segment = {'api.NETWORK_TYPE': ""} segment[api.NETWORK_TYPE] = p_const.TYPE_VLAN - self.assertTrue(self.driver.check_segment(segment)) + self.assertTrue(self.driver.check_segment_for_agent(segment)) # Validate a network type not currently supported segment[api.NETWORK_TYPE] = p_const.TYPE_GRE - self.assertFalse(self.driver.check_segment(segment)) + self.assertFalse(self.driver.check_segment_for_agent(segment)) def test_check_segment_allows_supported_network_types(self): - for network_type in self.driver.supported_network_types: + for network_type in self.driver.get_allowed_network_types(agent=None): segment = {api.NETWORK_TYPE: network_type} - self.assertTrue(self.driver.check_segment(segment)) + self.assertTrue(self.driver.check_segment_for_agent(segment)) class SriovMechVlanTestCase(SriovNicSwitchMechanismBaseTestCase,