From 3cac4d8f7d4343516ec335017dd783a887b9c4d6 Mon Sep 17 00:00:00 2001 From: Phil Day Date: Fri, 8 Feb 2013 17:47:56 +0000 Subject: Fixes a race condition on updating security group rules During creating the instance, compute manager makes an rpc call to "allocate_for_instance" from the network manager, which will in turn end up making a rpc cast to each compute_manager with an instance in the group(s) than need to be refreshed calling refresh_instance_security_rules. When an instance is being created is in a group that has a rule referring to itself, that chain will end up trying to refresh the rules for the instance which is still being created. That call will find its way down to do_refresh_instance_rules() in libvirt/firewall - which will in turn try to get network_info from the global "network_infos" in firewall. But the entry in network_infos for this instance might not of been added yet, as that only happens when the create of the instance calls "prepare_instance_filter which comes later in the sequence as part of driver.spawn The fix here adds a synchronisation lock to the incomming refresh call so that it is blocked until any in-progress thread on the instance is finished. Change-Id: I550e286aa4777b011633550109e18e03d63a4bbb --- nova/compute/manager.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index bb4af94a6..605c72839 100755 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -579,8 +579,13 @@ class ComputeManager(manager.SchedulerDependentManager): Passes straight through to the virtualization driver. + Synchronise the call beacuse we may still be in the middle of + creating the instance. """ - return self.driver.refresh_instance_security_rules(instance) + @lockutils.synchronized(instance['uuid'], 'nova-') + def _sync_refresh(): + return self.driver.refresh_instance_security_rules(instance) + return _sync_refresh() @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) def refresh_provider_fw_rules(self, context): -- cgit