Dont try to apply iptables rules in a endless loop

If the namespace does not exist the current behavior
is to try to apply the iptables rules forever in a
endless loop. This fills up the logs on the network
node and leads to outage.

Change-Id: I628b18a66f9478d7349fa1817431aae2f62ee105
Related-bug: #1623664
Related-bug: #1573073
This commit is contained in:
Saverio Proto 2017-03-27 16:39:16 +02:00 committed by Kevin Benton
parent 3d5d9e8957
commit 3889b0f214
2 changed files with 29 additions and 1 deletions

View File

@ -32,6 +32,7 @@ from oslo_utils import excutils
import six
from neutron._i18n import _, _LE, _LW
from neutron.agent.linux import ip_lib
from neutron.agent.linux import iptables_comments as ic
from neutron.agent.linux import utils as linux_utils
from neutron.common import exceptions as n_exc
@ -471,7 +472,20 @@ class IptablesManager(object):
args = ['%s-save' % (cmd,)]
if self.namespace:
args = ['ip', 'netns', 'exec', self.namespace] + args
save_output = self.execute(args, run_as_root=True)
try:
save_output = self.execute(args, run_as_root=True)
except RuntimeError:
# We could be racing with a cron job deleting namespaces.
# It is useless to try to apply iptables rules over and
# over again in a endless loop if the namespace does not
# exist.
with excutils.save_and_reraise_exception() as ctx:
if (self.namespace and not
ip_lib.IPWrapper().netns.exists(self.namespace)):
ctx.reraise = False
LOG.error("Namespace %s was deleted during IPTables "
"operations.", self.namespace)
return []
all_lines = save_output.split('\n')
commands = []
# Traverse tables in sorted order for predictable dump output

View File

@ -982,6 +982,20 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
{'wrap': True, 'top': False, 'rule': '-j DROP',
'chain': 'nonexistent'})
def test_iptables__apply_synchronized_no_namespace(self):
self.execute.side_effect = RuntimeError
# no namespace set so should raise
self.assertRaises(RuntimeError,
self.iptables._apply_synchronized)
self.iptables.namespace = 'test'
with mock.patch('neutron.agent.linux.ip_lib.IpNetnsCommand.exists',
return_value=True):
self.assertRaises(RuntimeError,
self.iptables._apply_synchronized)
with mock.patch('neutron.agent.linux.ip_lib.IpNetnsCommand.exists',
return_value=False):
self.assertEqual([], self.iptables._apply_synchronized())
def test_iptables_failure_with_no_failing_line_number(self):
with mock.patch.object(iptables_manager, "LOG") as log:
# generate Runtime errors on iptables-restore calls