From 881a93473c32a7c7e23a8e6dcede8394053408c6 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Thu, 20 Dec 2012 20:13:37 -0800 Subject: Eliminate race conditions in floating association This makes associating and disassociating floating ips atomic and idempotent. This means multiple concurrent messages will not leave behind iptables rules and concurrent request will not cause odd failures. Fixes bug 1092762 and bug 1092761. Change-Id: Idbcad6c1d2a3d4881cf7180b848ed3844fac4054 --- nova/db/api.py | 10 ++++++++-- nova/db/sqlalchemy/api.py | 3 +++ 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'nova/db') diff --git a/nova/db/api.py b/nova/db/api.py index 4acff8a99..3e350fc75 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -290,7 +290,8 @@ def floating_ip_destroy(context, address): def floating_ip_disassociate(context, address): """Disassociate a floating ip from a fixed ip by address. - :returns: the address of the existing fixed ip. + :returns: the address of the previous fixed ip or None + if the ip was not associated to an ip. """ return IMPL.floating_ip_disassociate(context, address) @@ -298,7 +299,12 @@ def floating_ip_disassociate(context, address): def floating_ip_fixed_ip_associate(context, floating_address, fixed_address, host): - """Associate a floating ip to a fixed_ip by address.""" + """Associate a floating ip to a fixed_ip by address. + + :returns: the address of the new fixed ip (fixed_address) or None + if the ip was already associated to the fixed ip. + """ + return IMPL.floating_ip_fixed_ip_associate(context, floating_address, fixed_address, diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index ec85ddcef..a24a5fe2d 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -764,9 +764,12 @@ def floating_ip_fixed_ip_associate(context, floating_address, fixed_ip_ref = fixed_ip_get_by_address(context, fixed_address, session=session) + if floating_ip_ref.fixed_ip_id == fixed_ip_ref["id"]: + return None floating_ip_ref.fixed_ip_id = fixed_ip_ref["id"] floating_ip_ref.host = host floating_ip_ref.save(session=session) + return fixed_address @require_context -- cgit