Not auto schedule router when sync routers from agent

In this patch, auto schedule router will be removed from sync_routers,
so that the reported bug can be fixed. And potential race can be avoid
accoridng to [1]

The result of patch will make the l3 agent can't get the router info
when the router is not bound to the l3 agent. And router in agent will
be removed during the agent processing. This makes sense, since, in
neutron server, the router is not tied to the agent. For DVR, if there
are service port in the agent host, the router info will still be
returned to l3 agent.

[1] https://review.openstack.org/#/c/317949/

Change-Id: Id0a8cf7537fefd626df06064f915d2de7c1680c6
Co-Authored-By: John Schwarz <jschwarz@redhat.com>
Closes-Bug: #1593653
This commit is contained in:
Hong Hui Xiao 2016-06-21 10:56:45 +00:00
parent 8e24ce70a1
commit 64726983f2
2 changed files with 31 additions and 34 deletions

View File

@ -90,11 +90,6 @@ class L3RpcCallback(object):
context = neutron_context.get_admin_context() context = neutron_context.get_admin_context()
if utils.is_extension_supported( if utils.is_extension_supported(
self.l3plugin, constants.L3_AGENT_SCHEDULER_EXT_ALIAS): self.l3plugin, constants.L3_AGENT_SCHEDULER_EXT_ALIAS):
# only auto schedule routers that were specifically requested;
# on agent full sync routers will be auto scheduled in
# get_router_ids()
if cfg.CONF.router_auto_schedule and router_ids:
self.l3plugin.auto_schedule_routers(context, host, router_ids)
routers = ( routers = (
self.l3plugin.list_active_sync_routers_on_active_l3_agent( self.l3plugin.list_active_sync_routers_on_active_l3_agent(
context, host, router_ids)) context, host, router_ids))

View File

@ -966,39 +966,41 @@ class OvsAgentSchedulerTestCase(OvsAgentSchedulerTestCaseBase):
self.assertIn(router_ids[0], [r['id'] for r in ret_a]) self.assertIn(router_ids[0], [r['id'] for r in ret_a])
self.assertIn(router_ids[2], [r['id'] for r in ret_a]) self.assertIn(router_ids[2], [r['id'] for r in ret_a])
def test_router_auto_schedule_for_specified_routers(self): def test_sync_router(self):
def _sync_router_with_ids(router_ids, exp_synced, exp_hosted, host_id):
ret_a = l3_rpc_cb.sync_routers(self.adminContext, host=L3_HOSTA,
router_ids=router_ids)
self.assertEqual(exp_synced, len(ret_a))
for r in router_ids:
self.assertIn(r, [r['id'] for r in ret_a])
host_routers = self._list_routers_hosted_by_l3_agent(host_id)
num_host_routers = len(host_routers['routers'])
self.assertEqual(exp_hosted, num_host_routers)
l3_rpc_cb = l3_rpc.L3RpcCallback() l3_rpc_cb = l3_rpc.L3RpcCallback()
self._register_agent_states() self._register_agent_states()
hosta_id = self._get_agent_id(constants.AGENT_TYPE_L3, L3_HOSTA) hosta_id = self._get_agent_id(constants.AGENT_TYPE_L3, L3_HOSTA)
with self.router() as v1,\ with self.router() as r1:
self.router() as v2,\ ret_a = l3_rpc_cb.sync_routers(self.adminContext, host=L3_HOSTA,
self.router() as v3,\ router_ids=[r1['router']['id']])
self.router() as v4: # Not return router to agent if the router is not bound to it.
routers = (v1, v2, v3, v4) self.assertEqual([], ret_a)
router_ids = [r['router']['id'] for r in routers] host_routers = self._list_routers_hosted_by_l3_agent(hosta_id)
# Sync router1 (router1 is scheduled) # No router will be auto scheduled.
_sync_router_with_ids([router_ids[0]], 1, 1, hosta_id) self.assertEqual(0, len(host_routers['routers']))
# Sync router1 only (no router is scheduled)
_sync_router_with_ids([router_ids[0]], 1, 1, hosta_id) def test_sync_dvr_router(self):
# Schedule router2 l3_rpc_cb = l3_rpc.L3RpcCallback()
_sync_router_with_ids([router_ids[1]], 1, 2, hosta_id) dvr_agents = self._register_dvr_agents()
# Sync router2 and router4 (router4 is scheduled)
_sync_router_with_ids([router_ids[1], router_ids[3]], with self.router() as r1, \
2, 3, hosta_id) mock.patch.object(self.l3plugin, 'get_subnet_ids_on_router',
# Sync all routers (router3 is scheduled) return_value=['fake_subnet_id']), \
_sync_router_with_ids(router_ids, 4, 4, hosta_id) mock.patch.object(self.l3plugin,
'_check_dvr_serviceable_ports_on_host',
return_value=True):
for l3_agent in dvr_agents:
host = l3_agent['host']
ret_a = l3_rpc_cb.sync_routers(self.adminContext, host=host,
router_ids=[r1['router']['id']])
router_ids = [r['id'] for r in ret_a]
# Return router to agent if there is dvr service port in agent.
self.assertIn(r1['router']['id'], router_ids)
host_routers = self._list_routers_hosted_by_l3_agent(
l3_agent['id'])
# No router will be auto scheduled.
self.assertEqual(0, len(host_routers['routers']))
def test_router_without_l3_agents(self): def test_router_without_l3_agents(self):
with self.subnet() as s: with self.subnet() as s: