]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Remove SELECT FOR UPDATE from delete_network and delete_subnet
authorrossella <rsblendido@suse.com>
Tue, 16 Sep 2014 22:30:12 +0000 (22:30 +0000)
committerrossella <rsblendido@suse.com>
Wed, 7 Jan 2015 15:13:25 +0000 (15:13 +0000)
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

index d9f56a3efd510b1386056052ce506b29517e58ac..344ba58e69b45588ff17d49c9a0fe9f703945ca1 100644 (file)
@@ -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)