diff options
author | Zuul <zuul@review.openstack.org> | 2018-06-27 14:09:01 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2018-06-27 14:09:01 +0000 |
commit | b66d5aed3652452473dcd3d6747068081b34968a (patch) | |
tree | 7cc1a4cdda47988a58cc7c4198aa5b3ec3a7322a | |
parent | aa48141706c2398a3754acd26d434192c259086e (diff) | |
parent | 3538cd6bc67e1ab8d904a5f96ec729ba50d5316d (diff) | |
download | ironic-python-agent-b66d5aed3652452473dcd3d6747068081b34968a.tar.gz |
Merge "[LLDP] Skip NICs that say they are ready but are unreadable." into stable/ocata
-rw-r--r-- | ironic_python_agent/netutils.py | 15 | ||||
-rw-r--r-- | ironic_python_agent/tests/unit/test_netutils.py | 45 | ||||
-rw-r--r-- | releasenotes/notes/LLDP-ignore-NICs-that-are-not-plugged-in-29213f0a701a72e4.yaml | 7 |
3 files changed, 63 insertions, 4 deletions
diff --git a/ironic_python_agent/netutils.py b/ironic_python_agent/netutils.py index 45b85a5d..5d38548d 100644 --- a/ironic_python_agent/netutils.py +++ b/ironic_python_agent/netutils.py @@ -182,10 +182,17 @@ def _get_lldp_info(interfaces): # Create a copy of interfaces to avoid deleting while iterating. for index, interface in enumerate(list(interfaces)): if s == interface[1]: - LOG.info('Found LLDP info for interface: %s', - interface[0]) - lldp_info[interface[0]] = ( - _receive_lldp_packets(s)) + try: + lldp_info[interface[0]] = _receive_lldp_packets(s) + except socket.error: + LOG.exception('Socket for network interface %s said ' + 'that it was ready to read we were ' + 'unable to read from the socket while ' + 'trying to get LLDP packet. Skipping ' + 'this network interface.', interface[0]) + else: + LOG.info('Found LLDP info for interface: %s', + interface[0]) # Remove interface from the list, only need one packet del interfaces[index] diff --git a/ironic_python_agent/tests/unit/test_netutils.py b/ironic_python_agent/tests/unit/test_netutils.py index 14c8b82e..0bdaaac8 100644 --- a/ironic_python_agent/tests/unit/test_netutils.py +++ b/ironic_python_agent/tests/unit/test_netutils.py @@ -13,6 +13,7 @@ # limitations under the License. import binascii +import socket import mock from oslo_config import cfg @@ -87,6 +88,50 @@ class TestNetutils(test_base.BaseTestCase): @mock.patch('fcntl.ioctl') @mock.patch('select.select') @mock.patch('socket.socket') + def test_get_lldp_info_socket_recv_error(self, sock_mock, select_mock, + fcntl_mock): + expected_lldp = { + 'eth1': [ + (0, b''), + (1, b'\x04\x88Z\x92\xecTY'), + (2, b'\x05Ethernet1/18'), + (3, b'\x00x')] + } + + interface_names = ['eth0', 'eth1'] + + sock1 = mock.Mock() + sock1.recv.side_effect = socket.error("BOOM") + + sock2 = mock.Mock() + sock2.recv.return_value = FAKE_LLDP_PACKET + sock2.fileno.return_value = 5 + + sock_mock.side_effect = [sock1, sock2] + + select_mock.side_effect = [ + ([sock1], [], []), + ([sock2], [], []) + ] + + lldp_info = netutils.get_lldp_info(interface_names) + self.assertEqual(expected_lldp, lldp_info) + + sock1.bind.assert_called_with(('eth0', netutils.LLDP_ETHERTYPE)) + sock2.bind.assert_called_with(('eth1', netutils.LLDP_ETHERTYPE)) + + sock1.recv.assert_called_with(1600) + sock2.recv.assert_called_with(1600) + + self.assertEqual(1, sock1.close.call_count) + self.assertEqual(1, sock2.close.call_count) + + # 2 interfaces, 2 calls to enter promiscuous mode, 1 to leave + self.assertEqual(6, fcntl_mock.call_count) + + @mock.patch('fcntl.ioctl') + @mock.patch('select.select') + @mock.patch('socket.socket') def test_get_lldp_info_multiple(self, sock_mock, select_mock, fcntl_mock): expected_lldp = { 'eth1': [ diff --git a/releasenotes/notes/LLDP-ignore-NICs-that-are-not-plugged-in-29213f0a701a72e4.yaml b/releasenotes/notes/LLDP-ignore-NICs-that-are-not-plugged-in-29213f0a701a72e4.yaml new file mode 100644 index 00000000..1f54af9b --- /dev/null +++ b/releasenotes/notes/LLDP-ignore-NICs-that-are-not-plugged-in-29213f0a701a72e4.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + Fixes bug in LLDP discovery code which lead to no LLDP information being + discovered for any network interface if one network interface raised an + exception, for example if the network interface incorrectly indicates its + ready to read. `<https://bugs.launchpad.net/ironic-python-agent/+bug/1665025>`_ |