Make libvirt Tpool proxying conditional
When running in eventlet mode we keep the original eventlet.tpool usage but when running in threading mode we call the functions directly on the thread of the caller. The patch_tpool_proxy() logic is removed from the libvirt driver as it was only needed for python old style classes which is not in use any more in python3 and the issue is not reproducible any more with virConnect even without the patching. ❯ python3 Python 3.12.10 (main, Apr 9 2025, 04:44:59) [GCC 14.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import eventlet >>> eventlet.monkey_patch() >>> from nova.virt.libvirt import host >>> h = host.Host(uri="qemu:///system") >>> h.get_connection() libvirt: error : internal error: could not initialize domain event timer URI qemu:///system does not support events: internal error: could not initialize domain event timer <libvirt.virConnect object at 0x7f829e94c170> >>> c = h.get_connection() >>> str(c) '<libvirt.virConnect object at 0x7f829e94c170>' >>> Signed-off-by: Balazs Gibizer <gibi@redhat.com> Change-Id: Ic60ab78cec2a9f9ba177568b69e738425e56cae1
This commit is contained in:
@@ -29998,6 +29998,16 @@ class LibvirtNonblockingTestCase(test.NoDBTestCase):
|
||||
group='libvirt')
|
||||
|
||||
def test_connection_to_primitive(self):
|
||||
if utils.concurrency_mode_threading():
|
||||
self.skipTest(
|
||||
"In threading mode nova does not use eventlet.tpool to "
|
||||
"wrap the libvirt calls. This test case asserts that the "
|
||||
"libvirt connection having eventlet.tpool.Proxy objects "
|
||||
"are serializable. See "
|
||||
"https://bugs.launchpad.net/nova/+bug/962840. "
|
||||
"As Proxy object is not present in threading mode this test "
|
||||
"is not valid. ")
|
||||
|
||||
# Test bug 962840.
|
||||
import nova.virt.libvirt.driver as libvirt_driver
|
||||
drvr = libvirt_driver.LibvirtDriver('')
|
||||
@@ -30007,6 +30017,13 @@ class LibvirtNonblockingTestCase(test.NoDBTestCase):
|
||||
@mock.patch.object(eventlet.tpool, 'execute')
|
||||
@mock.patch.object(objects.Service, 'get_by_compute_host')
|
||||
def test_tpool_execute_calls_libvirt(self, mock_svc, mock_execute):
|
||||
if utils.concurrency_mode_threading():
|
||||
self.skipTest(
|
||||
"In threading mode nova does not use eventlet.tpool to "
|
||||
"wrap the libvirt calls. This test case asserts that libvirt "
|
||||
"connect goes through the tpool, so in threading mode this "
|
||||
"test case is invalid.")
|
||||
|
||||
conn = fakelibvirt.virConnect()
|
||||
conn.is_expected = True
|
||||
|
||||
|
||||
@@ -2298,6 +2298,13 @@ class TestLibvirtSEVESSupported(TestLibvirtSEV):
|
||||
|
||||
class LibvirtTpoolProxyTestCase(test.NoDBTestCase):
|
||||
def setUp(self):
|
||||
if utils.concurrency_mode_threading():
|
||||
self.skipTest(
|
||||
"In threading mode nova does not use eventlet.tpool.Proxy to "
|
||||
"wrap the libvirt calls. This test asserts that such calls "
|
||||
"are returning Proxy objects. So these test cases are not "
|
||||
"valid.")
|
||||
|
||||
super(LibvirtTpoolProxyTestCase, self).setUp()
|
||||
|
||||
self.useFixture(nova_fixtures.LibvirtFixture())
|
||||
|
||||
+2
-2
@@ -1290,11 +1290,11 @@ def _log_executor_stats(executor):
|
||||
executor._delayed_work.unfinished_tasks, stats)
|
||||
|
||||
|
||||
def tpool_wrap(target):
|
||||
def tpool_wrap(target, autowrap=()):
|
||||
"""Wrap the target into an eventlet Tpool Proxy object if running
|
||||
in eventlet mode. In threading mode no wrapping is applied.
|
||||
"""
|
||||
if concurrency_mode_threading():
|
||||
return target
|
||||
else:
|
||||
return tpool.Proxy(target)
|
||||
return tpool.Proxy(target, autowrap=autowrap)
|
||||
|
||||
@@ -48,7 +48,6 @@ import uuid
|
||||
|
||||
from castellan import key_manager
|
||||
from copy import deepcopy
|
||||
from eventlet import tpool
|
||||
from lxml import etree
|
||||
from os_brick import encryptors
|
||||
from os_brick.encryptors import luks as luks_encryptor
|
||||
@@ -193,24 +192,6 @@ VOLUME_DRIVERS = {
|
||||
}
|
||||
|
||||
|
||||
def patch_tpool_proxy():
|
||||
"""eventlet.tpool.Proxy doesn't work with old-style class in __str__()
|
||||
or __repr__() calls. See bug #962840 for details.
|
||||
We perform a monkey patch to replace those two instance methods.
|
||||
"""
|
||||
|
||||
def str_method(self):
|
||||
return str(self._obj)
|
||||
|
||||
def repr_method(self):
|
||||
return repr(self._obj)
|
||||
|
||||
tpool.Proxy.__str__ = str_method
|
||||
tpool.Proxy.__repr__ = repr_method
|
||||
|
||||
|
||||
patch_tpool_proxy()
|
||||
|
||||
# For information about when MIN_{LIBVIRT,QEMU}_VERSION and
|
||||
# NEXT_MIN_{LIBVIRT,QEMU}_VERSION can be changed, consult the following:
|
||||
#
|
||||
|
||||
@@ -41,7 +41,6 @@ import typing as ty
|
||||
from eventlet import greenio
|
||||
from eventlet import greenthread
|
||||
from eventlet import patcher
|
||||
from eventlet import tpool
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import excutils
|
||||
@@ -195,7 +194,7 @@ class Host(object):
|
||||
# eventlet's event loop, starving all other greenthreads until
|
||||
# completion. eventlet's tpool.Proxy handles this situation for us by
|
||||
# executing proxied calls in a native thread.
|
||||
return tpool.Proxy(obj, autowrap=self._libvirt_proxy_classes)
|
||||
return utils.tpool_wrap(obj, autowrap=self._libvirt_proxy_classes)
|
||||
|
||||
def _native_thread(self):
|
||||
"""Receives async events coming in from libvirtd.
|
||||
|
||||
@@ -2,9 +2,11 @@ nova.tests.unit.console.rfb.test_authvencrypt.RFBAuthSchemeVeNCryptTestCase.test
|
||||
nova.tests.unit.console.rfb.test_authvencrypt.RFBAuthSchemeVeNCryptTestCase.test_security_handshake_without_x509
|
||||
nova.tests.unit.console.rfb.test_authvencrypt.RFBAuthSchemeVeNCryptTestCase.test_security_handshake_with_x509
|
||||
nova.tests.unit.test_context.ContextTestCase.test_scatter_gather_cells_queued_task_cancelled
|
||||
|
||||
# Wait until eventlet.Event is removed by https://review.opendev.org/c/openstack/nova/+/949754
|
||||
nova.tests.unit.virt.libvirt.test_driver.CacheConcurrencyTestCase.test_different_fname_concurrency
|
||||
nova.tests.unit.virt.libvirt.test_driver.CacheConcurrencyTestCase.test_same_fname_concurrency
|
||||
nova.tests.unit.virt.libvirt.test_driver.LibvirtDriverTestCase.test_rescue
|
||||
|
||||
nova.tests.unit.virt.libvirt.test_driver.TestUpdateProviderTree.test_image_cache_disk_reservation
|
||||
nova.tests.unit.virt.libvirt.test_driver.TestUpdateProviderTree.test_update_provider_tree
|
||||
nova.tests.unit.virt.libvirt.test_driver.TestUpdateProviderTree.test_update_provider_tree_for_pcpu_reshape
|
||||
@@ -18,47 +20,6 @@ nova.tests.unit.virt.libvirt.test_driver.TestUpdateProviderTree.test_update_prov
|
||||
nova.tests.unit.virt.libvirt.volume.test_mount.HostMountStateTestCase.test_mount_concurrent
|
||||
nova.tests.unit.virt.libvirt.volume.test_mount.HostMountStateTestCase.test_mount_concurrent_no_interfere
|
||||
nova.tests.unit.virt.libvirt.volume.test_mount.MountManagerTestCase.test_host_up_waits_for_completion
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_attach_detach_different_power_states
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_attach_detach_volume
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_block_stats
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_destroy_instance
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_force_hard_reboot
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_get_console_output
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_get_diagnostics
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_get_info
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_get_instance_diagnostics
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_get_instance_disk_info
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_get_mks_console
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_get_serial_console
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_get_spice_console
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_get_vnc_console
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_live_migration
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_live_migration_force_complete
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_pause
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_poll_rebooting_instances
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_power_off
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_power_on_powered_off
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_power_on_running
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_reboot
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_rescue
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_restore_running
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_restore_soft_deleted
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_resume_state_on_host_boot
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_resume_suspended_instance
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_resume_unsuspended_instance
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_set_admin_password
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_snapshot_running
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_soft_delete
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_spawn
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_suspend
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_swap_volume
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_trigger_crash_dump
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_unpause_paused_instance
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_unpause_unpaused_instance
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_unplug_vifs_with_destroy_vifs_false
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_unplug_vifs_with_destroy_vifs_true
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_unrescue_rescued_instance
|
||||
nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_unrescue_unrescued_instance
|
||||
nova.tests.unit.virt.vmwareapi.test_vm_util.VMwareVMUtilTestCase.test_create_vm_invalid_guestid
|
||||
# Independent failure ~10% with multiple possible error:
|
||||
# - sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) not an error
|
||||
|
||||
Reference in New Issue
Block a user