diff --git a/nova/tests/unit/virt/disk/vfs/test_guestfs.py b/nova/tests/unit/virt/disk/vfs/test_guestfs.py index 9cb879f70959..d0bd542ccfce 100644 --- a/nova/tests/unit/virt/disk/vfs/test_guestfs.py +++ b/nova/tests/unit/virt/disk/vfs/test_guestfs.py @@ -335,7 +335,8 @@ class VirtDiskVFSGuestFSTest(test.NoDBTestCase): m.launch.side_effect = Exception vfs = vfsimpl.VFSGuestFS(self.qcowfile) mock_access.return_value = False - with mock.patch('eventlet.tpool.Proxy', return_value=m): + self.flags(debug=False, group='guestfs') + with mock.patch('eventlet.tpool.Proxy', return_value=m) as tpool_mock: self.assertRaises(exception.LibguestfsCannotReadKernel, vfs.inspect_capabilities) m.add_drive.assert_called_once_with('/dev/null') @@ -343,3 +344,17 @@ class VirtDiskVFSGuestFSTest(test.NoDBTestCase): mock_access.assert_called_once_with('/boot/vmlinuz-kernel_name', mock.ANY) mock_uname.assert_called_once_with() + self.assertEqual(1, tpool_mock.call_count) + + def test_appliance_setup_inspect_capabilties_debug_mode(self): + """Asserts that we do not use an eventlet thread pool when guestfs + debug logging is enabled. + """ + # We can't actually mock guestfs.GuestFS because it's an optional + # native package import. All we really care about here is that + # eventlet isn't used. + self.flags(debug=True, group='guestfs') + vfs = vfsimpl.VFSGuestFS(self.qcowfile) + with mock.patch('eventlet.tpool.Proxy', + new_callable=mock.NonCallableMock): + vfs.inspect_capabilities() diff --git a/nova/virt/disk/vfs/guestfs.py b/nova/virt/disk/vfs/guestfs.py index 6e848bb72d82..84dddd875f37 100644 --- a/nova/virt/disk/vfs/guestfs.py +++ b/nova/virt/disk/vfs/guestfs.py @@ -75,7 +75,14 @@ class VFSGuestFS(vfs.VFS): def inspect_capabilities(self): """Determines whether guestfs is well configured.""" try: - g = tpool.Proxy(guestfs.GuestFS()) + # If guestfs debug is enabled, we can't launch in a thread because + # the debug logging callback can make eventlet try to switch + # threads and then the launch hangs, causing eternal sadness. + if CONF.guestfs.debug: + LOG.debug('Inspecting guestfs capabilities non-threaded.') + g = guestfs.GuestFS() + else: + g = tpool.Proxy(guestfs.GuestFS()) g.add_drive("/dev/null") # sic g.launch() except Exception as e: