Browse Source

DVR: optimize check_ports_exist_on_l3_agent()

Currently the function gets all ports on the subnet and iterates
through them to find dvr serviceable ports on a particular host.
This patch makes it a single DB query to see if any port exists
matching criterias.

Partial-Bug: #1513678

Conflicts:

	neutron/common/utils.py
	neutron/db/l3_agentschedulers_db.py

Change-Id: Ie17885497aacb8fda4a2c4a05f19d08991038557
Co-Authored-By: Oleg Bondarev <obondarev@mirantis.com>
(cherry picked from commit 226c999de3)
tags/7.0.3
Oleg Bondarev 4 years ago
parent
commit
0bd401c863
3 changed files with 32 additions and 14 deletions
  1. +1
    -0
      neutron/common/constants.py
  2. +13
    -4
      neutron/common/utils.py
  3. +18
    -10
      neutron/db/l3_agentschedulers_db.py

+ 1
- 0
neutron/common/constants.py View File

@@ -41,6 +41,7 @@ DEVICE_OWNER_ROUTER_SNAT = "network:router_centralized_snat"
DEVICE_OWNER_LOADBALANCER = "neutron:LOADBALANCER"
DEVICE_OWNER_LOADBALANCERV2 = "neutron:LOADBALANCERV2"

DEVICE_OWNER_COMPUTE_PREFIX = "compute:"
DEVICE_OWNER_PREFIXES = ["network:", "neutron:"]

# Collection used to identify devices owned by router interfaces.

+ 13
- 4
neutron/common/utils.py View File

@@ -360,6 +360,18 @@ class exception_logger(object):
return call


def get_other_dvr_serviced_device_owners():
"""Return device_owner names for ports that should be serviced by DVR

This doesn't return DEVICE_OWNER_COMPUTE_PREFIX since it is a
prefix, not a complete device_owner name, so should be handled
separately (see is_dvr_serviced() below)
"""
return [n_const.DEVICE_OWNER_LOADBALANCER,
n_const.DEVICE_OWNER_LOADBALANCERV2,
n_const.DEVICE_OWNER_DHCP]


def is_dvr_serviced(device_owner):
"""Check if the port need to be serviced by DVR

@@ -368,11 +380,8 @@ def is_dvr_serviced(device_owner):
if they are required for DVR or any service directly or
indirectly associated with DVR.
"""
dvr_serviced_device_owners = (n_const.DEVICE_OWNER_LOADBALANCER,
n_const.DEVICE_OWNER_LOADBALANCERV2,
n_const.DEVICE_OWNER_DHCP)
return (device_owner.startswith('compute:') or
device_owner in dvr_serviced_device_owners)
device_owner in get_other_dvr_serviced_device_owners())


def get_keystone_url(conf):

+ 18
- 10
neutron/db/l3_agentschedulers_db.py View File

@@ -32,7 +32,9 @@ from neutron.db import agents_db
from neutron.db import agentschedulers_db
from neutron.db import l3_attrs_db
from neutron.db import model_base
from neutron.db import models_v2
from neutron.extensions import l3agentscheduler
from neutron.extensions import portbindings
from neutron.i18n import _LE, _LI, _LW
from neutron import manager
from neutron.plugins.common import constants as service_constants
@@ -453,21 +455,27 @@ class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
if agentschedulers_db.AgentSchedulerDbMixin.is_eligible_agent(
active, l3_agent)]

def check_ports_exist_on_l3agent(
self, context, l3_agent, subnet_ids):
def check_ports_exist_on_l3agent(self, context, l3_agent, subnet_ids):
"""
This function checks for existence of dvr serviceable
ports on the host, running the input l3agent.
"""
# db query will return ports for all subnets if subnet_ids is empty,
# so need to check first
if not subnet_ids:
return False

core_plugin = manager.NeutronManager.get_plugin()
filter = {'fixed_ips': {'subnet_id': subnet_ids}}
ports = core_plugin.get_ports(context, filters=filter)
for port in ports:
if (n_utils.is_dvr_serviced(port['device_owner']) and
l3_agent['host'] == port['binding:host_id']):
return True

return False
filters = {'fixed_ips': {'subnet_id': subnet_ids},
portbindings.HOST_ID: [l3_agent['host']]}
ports_query = core_plugin._get_ports_query(context, filters=filters)
owner_filter = or_(
models_v2.Port.device_owner.startswith(
constants.DEVICE_OWNER_COMPUTE_PREFIX),
models_v2.Port.device_owner.in_(
n_utils.get_other_dvr_serviced_device_owners()))
ports_query = ports_query.filter(owner_filter)
return ports_query.first() is not None

def get_l3_agent_candidates(self, context, sync_router, l3_agents,
ignore_admin_state=False):

Loading…
Cancel
Save