Browse Source

Merge "Optimize DVR related port DB query" into stable/queens

changes/78/719978/1
Zuul 3 months ago
committed by Gerrit Code Review
parent
commit
96b5c014ab
4 changed files with 49 additions and 16 deletions
  1. +2
    -2
      neutron/api/rpc/handlers/l3_rpc.py
  2. +7
    -4
      neutron/db/db_base_plugin_common.py
  3. +31
    -10
      neutron/db/dvr_mac_db.py
  4. +9
    -0
      neutron/db/l3_dvr_db.py

+ 2
- 2
neutron/api/rpc/handlers/l3_rpc.py View File

@@ -290,8 +290,8 @@ class L3RpcCallback(object):
"""DVR: RPC called by dvr-agent to get all ports for subnet."""
subnet_id = kwargs.get('subnet_id')
LOG.debug("DVR: subnet_id: %s", subnet_id)
filters = {'fixed_ips': {'subnet_id': [subnet_id]}}
return self.plugin.get_ports(context, filters=filters)
return self.l3plugin.get_ports_under_dvr_connected_subnet(
context, subnet_id)

@db_api.retry_db_errors
def get_agent_gateway_port(self, context, **kwargs):


+ 7
- 4
neutron/db/db_base_plugin_common.py View File

@@ -202,7 +202,8 @@ class DbBasePluginCommon(common_db_mixin.CommonDbMixin):
return db_utils.resource_fields(res, fields)

def _make_port_dict(self, port, fields=None,
process_extensions=True):
process_extensions=True,
with_fixed_ips=True):
res = {"id": port["id"],
'name': port['name'],
"network_id": port["network_id"],
@@ -210,11 +211,13 @@ class DbBasePluginCommon(common_db_mixin.CommonDbMixin):
"mac_address": port["mac_address"],
"admin_state_up": port["admin_state_up"],
"status": port["status"],
"fixed_ips": [{'subnet_id': ip["subnet_id"],
'ip_address': ip["ip_address"]}
for ip in port["fixed_ips"]],
"device_id": port["device_id"],
"device_owner": port["device_owner"]}
if with_fixed_ips:
res["fixed_ips"] = [
{'subnet_id': ip["subnet_id"],
'ip_address': str(
ip["ip_address"])} for ip in port["fixed_ips"]]
# Call auxiliary extend functions, if any
if process_extensions:
resource_extend.apply_funcs(port_def.COLLECTION_NAME, res, port)


+ 31
- 10
neutron/db/dvr_mac_db.py View File

@@ -15,7 +15,6 @@

import netaddr

from neutron_lib.api.definitions import portbindings
from neutron_lib.callbacks import events
from neutron_lib.callbacks import registry
from neutron_lib.callbacks import resources
@@ -36,6 +35,7 @@ from neutron.db import api as db_api
from neutron.db import models_v2
from neutron.extensions import dvr as ext_dvr
from neutron.objects import router
from neutron.plugins.ml2 import models as ml2_models


LOG = logging.getLogger(__name__)
@@ -45,6 +45,18 @@ dvr_mac_db.register_db_dvr_mac_opts()
l3_dvr_db.register_db_l3_dvr_opts()


def get_ports_query_by_subnet_and_ip(context, subnet, ip_addresses=None):
query = context.session.query(models_v2.Port)
query = query.join(models_v2.IPAllocation)
query = query.filter(
models_v2.Port.id == models_v2.IPAllocation.port_id,
models_v2.IPAllocation.subnet_id == subnet)
if ip_addresses:
query = query.filter(
models_v2.IPAllocation.ip_address.in_(ip_addresses))
return query


@registry.has_registry_receivers
class DVRDbMixin(ext_dvr.DVRMacAddressPluginBase):
"""Mixin class to add dvr mac address to db_plugin_base_v2."""
@@ -146,18 +158,28 @@ class DVRDbMixin(ext_dvr.DVRMacAddressPluginBase):
:param subnet: subnet id to match and extract ports of interest
:returns: list -- Ports on the given subnet in the input host
"""

host_dvr_for_dhcp = cfg.CONF.host_dvr_for_dhcp
filters = {'fixed_ips': {'subnet_id': [subnet]},
portbindings.HOST_ID: [host]}
ports_query = self.plugin._get_ports_query(context, filters=filters)

query = context.session.query(models_v2.Port)
query = query.join(ml2_models.PortBinding)
query = query.join(models_v2.IPAllocation)
query = query.filter(
models_v2.Port.id == ml2_models.PortBinding.port_id,
models_v2.Port.id == models_v2.IPAllocation.port_id,
ml2_models.PortBinding.host == host,
models_v2.IPAllocation.subnet_id == subnet)
owner_filter = or_(
models_v2.Port.device_owner.startswith(
constants.DEVICE_OWNER_COMPUTE_PREFIX),
models_v2.Port.device_owner.in_(
utils.get_other_dvr_serviced_device_owners(host_dvr_for_dhcp)))
ports_query = ports_query.filter(owner_filter)

ports_query = query.filter(owner_filter)

ports = [
self.plugin._make_port_dict(port, process_extensions=False)
self.plugin._make_port_dict(port, process_extensions=False,
with_fixed_ips=False)
for port in ports_query.all()
]
LOG.debug("Returning list of dvr serviced ports on host %(host)s"
@@ -185,11 +207,10 @@ class DVRDbMixin(ext_dvr.DVRMacAddressPluginBase):
else:
ip_address = subnet_info['gateway_ip']

filter = {'fixed_ips': {'subnet_id': [subnet],
'ip_address': [ip_address]}}
query = get_ports_query_by_subnet_and_ip(
context, subnet, [ip_address])
internal_gateway_ports = query.all()

internal_gateway_ports = self.plugin.get_ports(
context, filters=filter)
if not internal_gateway_ports:
LOG.error("Could not retrieve gateway port "
"for subnet %s", subnet_info)


+ 9
- 0
neutron/db/l3_dvr_db.py View File

@@ -39,6 +39,7 @@ from neutron.common import constants as l3_const
from neutron.common import utils as n_utils
from neutron.conf.db import l3_dvr_db
from neutron.db import api as db_api
from neutron.db import dvr_mac_db
from neutron.db import l3_attrs_db
from neutron.db import l3_db
from neutron.db.models import allowed_address_pair as aap_models
@@ -1236,6 +1237,14 @@ class L3_NAT_with_dvr_db_mixin(_DVRAgentInterfaceMixin,
self.get_router(context.elevated(), router_id))
return False

def get_ports_under_dvr_connected_subnet(self, context, subnet_id):
query = dvr_mac_db.get_ports_query_by_subnet_and_ip(context, subnet_id)
return [
self.l3plugin._core_plugin._make_port_dict(
port, process_extensions=False)
for port in query.all()
]


def is_distributed_router(router):
"""Return True if router to be handled is distributed."""


Loading…
Cancel
Save