diff --git a/nova/storage/rbd_utils.py b/nova/storage/rbd_utils.py index d0436c8e90..9a34526a04 100644 --- a/nova/storage/rbd_utils.py +++ b/nova/storage/rbd_utils.py @@ -16,8 +16,6 @@ import urllib -from eventlet import tpool - from oslo_concurrency import processutils from oslo_log import log as logging from oslo_serialization import jsonutils @@ -28,6 +26,7 @@ from oslo_utils import excutils import nova.conf from nova import exception from nova.i18n import _ +from nova import utils try: import rados @@ -52,7 +51,7 @@ class RbdProxy(object): """ def __init__(self): - self._rbd = tpool.Proxy(rbd.RBD()) + self._rbd = utils.tpool_wrap(rbd.RBD()) def __getattr__(self, attr): return getattr(self._rbd, attr) @@ -72,9 +71,8 @@ class RBDVolumeProxy(object): read_only=False): client, ioctx = driver._connect_to_rados(pool) try: - self.volume = tpool.Proxy(rbd.Image(ioctx, name, - snapshot=snapshot, - read_only=read_only)) + self.volume = utils.tpool_wrap( + rbd.Image(ioctx, name, snapshot=snapshot, read_only=read_only)) except rbd.ImageNotFound: with excutils.save_and_reraise_exception(): LOG.debug("rbd image %s does not exist", name) diff --git a/nova/tests/unit/storage/test_rbd.py b/nova/tests/unit/storage/test_rbd.py index 923b09b846..6fd15a83fb 100644 --- a/nova/tests/unit/storage/test_rbd.py +++ b/nova/tests/unit/storage/test_rbd.py @@ -22,6 +22,7 @@ from nova import exception from nova import objects from nova.storage import rbd_utils from nova import test +from nova import utils CEPH_MON_DUMP = r"""dumped monmap epoch 1 @@ -147,7 +148,10 @@ class RbdTestCase(test.NoDBTestCase): def test_rbdproxy_wraps_rbd(self): proxy = rbd_utils.RbdProxy() - self.assertIsInstance(proxy._rbd, tpool.Proxy) + if utils.concurrency_mode_threading(): + self.assertEqual(proxy._rbd, self.mock_rbd.RBD.return_value) + else: + self.assertIsInstance(proxy._rbd, tpool.Proxy) def test_rbdproxy_attribute_access_proxying(self): client = mock.MagicMock(ioctx='fake_ioctx') diff --git a/nova/tests/unit/test_utils.py b/nova/tests/unit/test_utils.py index 8a5d120602..32827593a5 100644 --- a/nova/tests/unit/test_utils.py +++ b/nova/tests/unit/test_utils.py @@ -232,6 +232,22 @@ class GenericUtilsTestCase(test.NoDBTestCase): project_id = '9b9e3c847e904b0686e8ffb20e4c6381' self.assertEqual('', utils.generate_hostid(None, project_id)) + @mock.patch('nova.utils.concurrency_mode_threading', return_value=False) + def test_tpool_wrap_eventlet(self, mock_concurrency_mode): + mock_target = mock.MagicMock() + target = utils.tpool_wrap(mock_target) + + self.assertEqual(target._obj, mock_target) + mock_concurrency_mode.assert_called_once_with() + + @mock.patch('nova.utils.concurrency_mode_threading', return_value=True) + def test_tpool_wrap_threading(self, mock_concurrency_mode): + mock_target = mock.MagicMock() + target = utils.tpool_wrap(mock_target) + + self.assertEqual(target, mock_target) + mock_concurrency_mode.assert_called_once_with() + class TestCachedFile(test.NoDBTestCase): @mock.patch('os.path.getmtime', return_value=1) diff --git a/nova/utils.py b/nova/utils.py index ae4fea3752..792095dd10 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -1288,3 +1288,13 @@ def _log_executor_stats(executor): name, len(executor._pool.coroutines_running), executor._pool.size, executor._delayed_work.unfinished_tasks, stats) + + +def tpool_wrap(target): + """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) diff --git a/threading_unit_test_excludes.txt b/threading_unit_test_excludes.txt index 9f3417ced3..4d88fcfab8 100644 --- a/threading_unit_test_excludes.txt +++ b/threading_unit_test_excludes.txt @@ -1,13 +1,6 @@ nova.tests.unit.console.rfb.test_authvencrypt.RFBAuthSchemeVeNCryptTestCase.test_security_handshake_fails_on_ssl_failure 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.storage.test_rbd.RbdTestCase.test_cleanup_volumes -nova.tests.unit.storage.test_rbd.RbdTestCase.test_cleanup_volumes_fail_not_found -nova.tests.unit.storage.test_rbd.RbdTestCase.test_cleanup_volumes_fail_other -nova.tests.unit.storage.test_rbd.RbdTestCase.test_cleanup_volumes_fail_snapshots -nova.tests.unit.storage.test_rbd.RbdTestCase.test_cleanup_volumes_pending_resize -nova.tests.unit.storage.test_rbd.RbdTestCase.test_cleanup_volumes_reverting_resize -nova.tests.unit.storage.test_rbd.RbdTestCase.test_destroy_volume nova.tests.unit.test_context.ContextTestCase.test_scatter_gather_cells_queued_task_cancelled nova.tests.unit.virt.libvirt.test_driver.CacheConcurrencyTestCase.test_different_fname_concurrency nova.tests.unit.virt.libvirt.test_driver.CacheConcurrencyTestCase.test_same_fname_concurrency