Build socket list right before select call

This will make sure the socket list and the interface list are
always in sync, and the select call is on the right list of
sockets.

Co-Authored-By: Dmitry Tantsur <dtantsur@redhat.com>
Closes-Bug: #1533892
Change-Id: Id6710f4648203b7d476a2a16ea647224baca1bb9
This commit is contained in:
Robert Li 2016-01-14 07:54:29 -05:00 committed by Dmitry Tantsur
parent d34bc0559c
commit 9e4b769055
3 changed files with 13 additions and 3 deletions

View File

@ -162,13 +162,12 @@ def _get_lldp_info(interfaces):
if not interfaces:
return {}
socks = [interface[1] for interface in interfaces]
while interfaces:
LOG.info('Waiting on LLDP info for interfaces: %(interfaces)s, '
'timeout: %(timeout)s', {'interfaces': interfaces,
'timeout': CONF.lldp_timeout})
socks = [interface[1] for interface in interfaces]
# rlist is a list of sockets ready for reading
rlist, _, _ = select.select(socks, [], [], CONF.lldp_timeout)
if not rlist:

View File

@ -113,7 +113,8 @@ class TestNetutils(test_base.BaseTestCase):
sock_mock.side_effect = [sock1, sock2]
select_mock.side_effect = [
([sock1, sock2], [], []),
([sock1], [], []),
([sock2], [], []),
]
lldp_info = netutils.get_lldp_info(interface_names)
@ -131,6 +132,12 @@ class TestNetutils(test_base.BaseTestCase):
# 2 interfaces, 2 calls to enter promiscuous mode, 1 to leave
self.assertEqual(6, fcntl_mock.call_count)
expected_calls = [
mock.call([sock1, sock2], [], [], cfg.CONF.lldp_timeout),
mock.call([sock2], [], [], cfg.CONF.lldp_timeout),
]
self.assertEqual(expected_calls, select_mock.call_args_list)
@mock.patch('fcntl.ioctl')
@mock.patch('select.select')
@mock.patch('socket.socket')

View File

@ -0,0 +1,4 @@
---
fixes:
- Fixed incorrect invocation of "select" which could cause LLDP collection
to hang under certain conditions.