SRIOV: don't block report_state with device count

The device count process can be quite slow on a system with
lots of interfaces. Doing this during report_state can block
it long enough that the agent will be reported as dead and
bindings will fail.

This adjusts the logic to only update the configuration during
the normal device retrieval for the scan loop. This will leave
the report_state loop unblocked by the operation so the agent
doesn't get reported as dead (which blocks port binding).

Closes-Bug: #1648206
Change-Id: Iff45fb6617974b1eceeed238a8d9e958f874f12b
(cherry picked from commit 1a2a71baf3)
This commit is contained in:
Kevin Benton 2016-12-07 11:33:46 -08:00 committed by Alexander Ignatov
parent 5a713b4324
commit 151af89ddc
2 changed files with 20 additions and 2 deletions

View File

@ -173,8 +173,6 @@ class SriovNicSwitchAgent(object):
def _report_state(self):
try:
devices = len(self.eswitch_mgr.get_assigned_devices_info())
self.agent_state.get('configurations')['devices'] = devices
self.state_rpc.report_state(self.context,
self.agent_state)
@ -197,6 +195,7 @@ class SriovNicSwitchAgent(object):
def scan_devices(self, registered_devices, updated_devices):
curr_devices = self.eswitch_mgr.get_assigned_devices_info()
self.agent_state.get('configurations')['devices'] = len(curr_devices)
device_info = {}
device_info['current'] = curr_devices
device_info['added'] = curr_devices - registered_devices

View File

@ -55,6 +55,25 @@ class TestSriovAgent(base.BaseTestCase):
self.agent = sriov_nic_agent.SriovNicSwitchAgent({}, {}, 0)
@mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent.eswitch_manager"
".ESwitchManager.get_assigned_devices_info", return_value=set())
@mock.patch.object(agent_rpc.PluginReportStateAPI, 'report_state')
def test_cached_device_count_report_state(self, report_state, get_dev):
self.agent._report_state()
agent_conf = self.agent.agent_state['configurations']
# ensure devices aren't calculated until first scan_devices call
self.assertNotIn('devices', agent_conf)
self.agent.scan_devices(set(), set())
self.assertEqual(0, agent_conf['devices'])
# ensure report_state doesn't call get_dev
get_dev.reset_mock()
get_dev.return_value = set(['dev1', 'dev2'])
self.agent._report_state()
self.assertEqual(0, agent_conf['devices'])
# after a device scan, conf should bump to 2
self.agent.scan_devices(set(), set())
self.assertEqual(2, agent_conf['devices'])
@mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent.pci_lib."
"PciDeviceIPWrapper.get_assigned_macs",
return_value=[(DEVICE_MAC, PCI_SLOT)])