1
commit ba585524e32965697c1a44c8fd743dea060bb1af
2
Author: Michael Still <mikal@stillhq.com>
3
Date: Thu Oct 11 15:46:11 2012 +1100
5
Avoid RPC calls while holding iptables lock.
7
This exhibitied itself as very slow instance starts on a Canonical
8
test cluster. This was because do_referesh_security_group_rules()
9
was making rpc calls while holding the iptables lock. This refactor
10
avoids that while making no functional changes (I hope).
12
This should resolve bug 1062314.
14
Change-Id: I36f805bd72f7bd06082cfe96c58d637203bcffb7
16
diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py
17
index 8861eb8..7af877f 100644
18
--- a/nova/tests/test_libvirt.py
19
+++ b/nova/tests/test_libvirt.py
20
@@ -3142,11 +3142,23 @@ class IptablesFirewallTestCase(test.TestCase):
21
def test_do_refresh_security_group_rules(self):
22
instance_ref = self._create_instance_ref()
23
self.mox.StubOutWithMock(self.fw,
25
+ self.mox.StubOutWithMock(self.fw,
26
'add_filters_for_instance',
27
use_mock_anything=True)
29
+ self.fw.instance_rules(instance_ref,
30
+ mox.IgnoreArg()).AndReturn((None, None))
31
+ self.fw.add_filters_for_instance(instance_ref, mox.IgnoreArg(),
33
+ self.fw.instance_rules(instance_ref,
34
+ mox.IgnoreArg()).AndReturn((None, None))
35
+ self.fw.add_filters_for_instance(instance_ref, mox.IgnoreArg(),
37
+ self.mox.ReplayAll()
39
self.fw.prepare_instance_filter(instance_ref, mox.IgnoreArg())
40
self.fw.instances[instance_ref['id']] = instance_ref
41
- self.mox.ReplayAll()
42
self.fw.do_refresh_security_group_rules("fake")
44
def test_unfilter_instance_undefines_nwfilter(self):
45
diff --git a/nova/virt/firewall.py b/nova/virt/firewall.py
46
index eb14a92..3e2ba5d 100644
47
--- a/nova/virt/firewall.py
48
+++ b/nova/virt/firewall.py
49
@@ -182,7 +182,8 @@ class IptablesFirewallDriver(FirewallDriver):
51
self.instances[instance['id']] = instance
52
self.network_infos[instance['id']] = network_info
53
- self.add_filters_for_instance(instance)
54
+ ipv4_rules, ipv6_rules = self.instance_rules(instance, network_info)
55
+ self.add_filters_for_instance(instance, ipv4_rules, ipv6_rules)
56
LOG.debug(_('Filters added to instance'), instance=instance)
57
self.refresh_provider_fw_rules()
58
LOG.debug(_('Provider Firewall Rules refreshed'), instance=instance)
59
@@ -218,7 +219,8 @@ class IptablesFirewallDriver(FirewallDriver):
60
for rule in ipv6_rules:
61
self.iptables.ipv6['filter'].add_rule(chain_name, rule)
63
- def add_filters_for_instance(self, instance):
64
+ def add_filters_for_instance(self, instance, inst_ipv4_rules,
66
network_info = self.network_infos[instance['id']]
67
chain_name = self._instance_chain_name(instance)
69
@@ -227,8 +229,7 @@ class IptablesFirewallDriver(FirewallDriver):
70
ipv4_rules, ipv6_rules = self._filters_for_instance(chain_name,
72
self._add_filters('local', ipv4_rules, ipv6_rules)
73
- ipv4_rules, ipv6_rules = self.instance_rules(instance, network_info)
74
- self._add_filters(chain_name, ipv4_rules, ipv6_rules)
75
+ self._add_filters(chain_name, inst_ipv4_rules, inst_ipv6_rules)
77
def remove_filters_for_instance(self, instance):
78
chain_name = self._instance_chain_name(instance)
79
@@ -430,15 +431,22 @@ class IptablesFirewallDriver(FirewallDriver):
82
@utils.synchronized('iptables', external=True)
83
+ def _inner_do_refresh_rules(self, instance, ipv4_rules,
85
+ self.remove_filters_for_instance(instance)
86
+ self.add_filters_for_instance(instance, ipv4_rules, ipv6_rules)
88
def do_refresh_security_group_rules(self, security_group):
89
for instance in self.instances.values():
90
- self.remove_filters_for_instance(instance)
91
- self.add_filters_for_instance(instance)
92
+ network_info = self.network_infos[instance['id']]
93
+ ipv4_rules, ipv6_rules = self.instance_rules(instance,
95
+ self._inner_do_refresh_rules(instance, ipv4_rules, ipv6_rules)
97
- @utils.synchronized('iptables', external=True)
98
def do_refresh_instance_rules(self, instance):
99
- self.remove_filters_for_instance(instance)
100
- self.add_filters_for_instance(instance)
101
+ network_info = self.network_infos[instance['id']]
102
+ ipv4_rules, ipv6_rules = self.instance_rules(instance, network_info)
103
+ self._inner_do_refresh_rules(instance, ipv4_rules, ipv6_rules)
105
def refresh_provider_fw_rules(self):
106
"""See :class:`FirewallDriver` docs."""