Use of logging in native thread causes deadlock connecting to libvirtd
When connecting to libvirtd daemon we were calling the _connect
method in a native thread. The use of logging in this method hit this
bug in eventlet https://bitbucket.org/eventlet/eventlet/issue/137/
causing nova-compute to hang.
Closes-Bug: #1252409
Conflicts:
nova/virt/libvirt/driver.py
NOTE(mriedem): The conflict is due to set_host_enabled
being used in the original change in Icehouse and the
option rename for libvirt_nonblocking.
Change-Id: I0d22c3ed1b3288aeb1afae130f11a4f38dc6440a
(cherry picked from commit e4b0d8e944
)
This commit is contained in:
parent
fd5b2bd67f
commit
48d19691e2
|
@ -7391,6 +7391,19 @@ class LibvirtNonblockingTestCase(test.TestCase):
|
|||
connection = libvirt_driver.LibvirtDriver('')
|
||||
jsonutils.to_primitive(connection._conn, convert_instances=True)
|
||||
|
||||
def test_tpool_execute_calls_libvirt(self):
|
||||
self.mox.StubOutWithMock(eventlet.tpool, 'execute')
|
||||
conn = libvirt.virConnect()
|
||||
conn.is_expected = True
|
||||
eventlet.tpool.execute(
|
||||
libvirt.openAuth, 'test:///default',
|
||||
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(conn)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
driver = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
c = driver._get_connection()
|
||||
self.assertEqual(True, c.is_expected)
|
||||
|
||||
|
||||
class LibvirtVolumeSnapshotTestCase(test.TestCase):
|
||||
"""Tests for libvirtDriver.volume_snapshot_create/delete."""
|
||||
|
|
|
@ -583,12 +583,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
def _get_new_connection(self):
|
||||
# call with _wrapped_conn_lock held
|
||||
LOG.debug(_('Connecting to libvirt: %s'), self.uri())
|
||||
if not CONF.libvirt_nonblocking:
|
||||
wrapped_conn = self._connect(self.uri(), self.read_only)
|
||||
else:
|
||||
wrapped_conn = tpool.proxy_call(
|
||||
(libvirt.virDomain, libvirt.virConnect),
|
||||
self._connect, self.uri(), self.read_only)
|
||||
wrapped_conn = self._connect(self.uri(), self.read_only)
|
||||
|
||||
self._wrapped_conn = wrapped_conn
|
||||
|
||||
|
@ -685,7 +680,15 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
flags = 0
|
||||
if read_only:
|
||||
flags = libvirt.VIR_CONNECT_RO
|
||||
return libvirt.openAuth(uri, auth, flags)
|
||||
if not CONF.libvirt_nonblocking:
|
||||
return libvirt.openAuth(uri, auth, flags)
|
||||
else:
|
||||
# tpool.proxy_call creates a native thread. Due to limitations
|
||||
# with eventlet locking we cannot use the logging API inside
|
||||
# the called function.
|
||||
return tpool.proxy_call(
|
||||
(libvirt.virDomain, libvirt.virConnect),
|
||||
libvirt.openAuth, uri, auth, flags)
|
||||
except libvirt.libvirtError as ex:
|
||||
LOG.exception(_("Connection to libvirt failed: %s"), ex)
|
||||
payload = dict(ip=LibvirtDriver.get_host_ip_addr(),
|
||||
|
|
Loading…
Reference in New Issue