Skip to content

Commit

Permalink
Fix nova-network MAC collision logic
Browse files Browse the repository at this point in the history
The exception being caught and transformed in sqlalchemy/api.py
was incorrect, causing nova-network to miss it in the MAC
collision retry loop.

This patch corrects that and adds a test of the collision logic.

Backports the fix for bug 1059366

Change-Id: I89d17eb8606a18f102e4de0dc76c77205cafbc8d
  • Loading branch information
kk7ds authored and openstack-gerrit committed Oct 31, 2012
1 parent 804f858 commit 5ccd691
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
2 changes: 1 addition & 1 deletion nova/db/sqlalchemy/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1278,7 +1278,7 @@ def virtual_interface_create(context, values):
vif_ref = models.VirtualInterface()
vif_ref.update(values)
vif_ref.save()
except IntegrityError:
except exception.DBError:
raise exception.VirtualInterfaceCreateException()

return vif_ref
Expand Down
33 changes: 33 additions & 0 deletions nova/tests/network/test_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

from nova import context
from nova import db
from nova.db.sqlalchemy import models
from nova import exception
from nova.network import linux_net
from nova.network import manager as network_manager
Expand Down Expand Up @@ -1752,6 +1753,38 @@ def fake_domains(context):
self.network.delete_dns_domain(context_admin, domain1)
self.network.delete_dns_domain(context_admin, domain2)

def test_mac_conflicts(self):
"""Make sure MAC collisions are retried"""
self.flags(create_unique_mac_address_attempts=3)
ctxt = context.RequestContext('testuser', 'testproject', is_admin=True)
macs = ['bb:bb:bb:bb:bb:bb', 'aa:aa:aa:aa:aa:aa']

# Create a VIF with aa:aa:aa:aa:aa:aa
crash_test_dummy_vif = {
'address': macs[1],
'instance_uuid': 'fake_uuid',
'network_id': 'fake_net',
'uuid': 'fake_uuid',
}
self.network.db.virtual_interface_create(ctxt, crash_test_dummy_vif)

# Hand out a collision first, then a legit MAC
def fake_gen_mac():
return macs.pop()
self.stubs.Set(utils, 'generate_mac_address', fake_gen_mac)

# SQLite doesn't seem to honor the uniqueness constraint on the
# address column, so fake the collision-avoidance here
def fake_vif_save(vif):
if vif.address == crash_test_dummy_vif['address']:
raise exception.DBError("If you're smart, you'll retry!")
self.stubs.Set(models.VirtualInterface, 'save', fake_vif_save)

# Attempt to add another and make sure that both MACs are consumed
# by the retry loop
self.network.add_virtual_interface(ctxt, 'fake_uuid', 'fake_net')
self.assertEqual(macs, [])


class NetworkPolicyTestCase(test.TestCase):
def setUp(self):
Expand Down

0 comments on commit 5ccd691

Please sign in to comment.