diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index cacee48dbb0d..6bd1db5ca4ff 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -905,21 +905,14 @@ def floating_ip_fixed_ip_associate(context, floating_address, @_retry_on_deadlock def floating_ip_deallocate(context, address): session = get_session() - with session.begin(): - floating_ip_ref = model_query(context, models.FloatingIp, - session=session).\ - filter_by(address=address).\ - filter(models.FloatingIp.project_id != null()).\ - with_lockmode('update').\ - first() - - if floating_ip_ref: - floating_ip_ref.update({'project_id': None, - 'host': None, - 'auto_assigned': False}) - - return floating_ip_ref + return model_query(context, models.FloatingIp, session=session).\ + filter_by(address=address).\ + filter(models.FloatingIp.project_id != null()).\ + update({'project_id': None, + 'host': None, + 'auto_assigned': False}, + synchronize_session=False) @require_context diff --git a/nova/network/floating_ips.py b/nova/network/floating_ips.py index 02beaf122b40..345f51dbb435 100644 --- a/nova/network/floating_ips.py +++ b/nova/network/floating_ips.py @@ -278,10 +278,10 @@ class FloatingIP(object): LOG.exception(_("Failed to update usages deallocating " "floating IP")) - floating_ip_ref = objects.FloatingIP.deallocate(context, address) - # floating_ip_ref will be None if concurrently another + rows_updated = objects.FloatingIP.deallocate(context, address) + # number of updated rows will be 0 if concurrently another # API call has also deallocated the same floating ip - if floating_ip_ref is None: + if not rows_updated: if reservations: QUOTAS.rollback(context, reservations, project_id=project_id) else: diff --git a/nova/tests/db/test_db_api.py b/nova/tests/db/test_db_api.py index 9ffa0241e5d5..90c5c002c63a 100644 --- a/nova/tests/db/test_db_api.py +++ b/nova/tests/db/test_db_api.py @@ -3894,13 +3894,17 @@ class FloatingIpTestCase(test.TestCase, ModelsObjectComparatorMixin): def test_floating_ip_deallocate(self): values = {'address': '1.1.1.1', 'project_id': 'fake', 'host': 'fake'} float_ip = self._create_floating_ip(values) - db.floating_ip_deallocate(self.ctxt, float_ip.address) + rows_updated = db.floating_ip_deallocate(self.ctxt, float_ip.address) + self.assertEqual(1, rows_updated) updated_float_ip = db.floating_ip_get(self.ctxt, float_ip.id) self.assertIsNone(updated_float_ip.project_id) self.assertIsNone(updated_float_ip.host) self.assertFalse(updated_float_ip.auto_assigned) + def test_floating_ip_deallocate_address_not_found(self): + self.assertEqual(0, db.floating_ip_deallocate(self.ctxt, '2.2.2.2')) + def test_floating_ip_destroy(self): addresses = ['1.1.1.1', '1.1.1.2', '1.1.1.3'] float_ips = [self._create_floating_ip({'address': addr})