From be6c51ccd72a3cea02e5feef1b6162b451a88bd1 Mon Sep 17 00:00:00 2001 From: rossella Date: Tue, 16 Sep 2014 22:30:12 +0000 Subject: [PATCH] Remove SELECT FOR UPDATE from delete_network and delete_subnet delete_network and delete_subnet instead of using SELECT FOR UPDATE delete the ports that are allowed to be auto deleted straight away. Then a check is performed, if there are ports still associated with the network or the subnet that cannot be autodeleted, an exception is raised. The operation will be rolled back. Partial-bug: #1331564 Change-Id: I29178204b3a220c1c6010f59272981fb1b4099fe --- neutron/db/db_base_plugin_v2.py | 58 ++++++++++++++++----------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/neutron/db/db_base_plugin_v2.py b/neutron/db/db_base_plugin_v2.py index d9f56a3ef..344ba58e6 100644 --- a/neutron/db/db_base_plugin_v2.py +++ b/neutron/db/db_base_plugin_v2.py @@ -935,23 +935,16 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2, with context.session.begin(subtransactions=True): network = self._get_network(context, id) - filters = {'network_id': [id]} - # NOTE(armando-migliaccio): stick with base plugin - query = context.session.query( - models_v2.Port).enable_eagerloads(False) - ports = self._apply_filters_to_query( - query, models_v2.Port, filters).with_lockmode('update') - - # check if there are any tenant owned ports in-use - only_auto_del = all(p['device_owner'] in AUTO_DELETE_PORT_OWNERS - for p in ports) - - if not only_auto_del: - raise n_exc.NetworkInUse(net_id=id) + context.session.query(models_v2.Port).filter_by( + network_id=id).filter( + models_v2.Port.device_owner. + in_(AUTO_DELETE_PORT_OWNERS)).delete(synchronize_session=False) + + port_in_use = context.session.query(models_v2.Port).filter_by( + network_id=id).first() - # clean up network owned ports - for port in ports: - self._delete_port(context, port['id']) + if port_in_use: + raise n_exc.NetworkInUse(net_id=id) # clean up subnets subnets = self._get_subnets_by_network(context, id) @@ -1268,24 +1261,29 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2, def delete_subnet(self, context, id): with context.session.begin(subtransactions=True): subnet = self._get_subnet(context, id) - # Check if any tenant owned ports are using this subnet - allocated = (context.session.query(models_v2.IPAllocation). - filter_by(subnet_id=subnet['id']). - join(models_v2.Port). - filter_by(network_id=subnet['network_id']). - with_lockmode('update')) - + # Delete all network owned ports + qry_network_ports = ( + context.session.query(models_v2.IPAllocation). + filter_by(subnet_id=subnet['id']). + join(models_v2.Port)) # Remove network owned ports, and delete IP allocations # for IPv6 addresses which were automatically generated # via SLAAC is_ipv6_slaac_subnet = ipv6_utils.is_slaac_subnet(subnet) - for a in allocated: - if (is_ipv6_slaac_subnet or - a.ports.device_owner in AUTO_DELETE_PORT_OWNERS): - NeutronDbPluginV2._delete_ip_allocation( - context, subnet.network_id, id, a.ip_address) - else: - raise n_exc.SubnetInUse(subnet_id=id) + if not is_ipv6_slaac_subnet: + qry_network_ports = ( + qry_network_ports.filter(models_v2.Port.device_owner. + in_(AUTO_DELETE_PORT_OWNERS))) + network_ports = qry_network_ports.all() + if network_ports: + map(context.session.delete, network_ports) + # Check if there are tenant owned ports + tenant_ports = (context.session.query(models_v2.IPAllocation). + filter_by(subnet_id=subnet['id']). + join(models_v2.Port). + filter_by(network_id=subnet['network_id']).first()) + if tenant_ports: + raise n_exc.SubnetInUse(subnet_id=id) context.session.delete(subnet) -- 2.45.2