Skip to content

Commit

Permalink
libvirt: Wrap un-proxied listDevices() and listAllDevices()
Browse files Browse the repository at this point in the history
This is similar to change I668643c836d46a25df46d4c99a973af5e50a39db
where the objects returned in a list from a libvirt call were not
tpool.Proxy wrapped. Because the objects are not wrapped, calling
methods on them such as listCaps() can block all other greenthreads
and can cause nova-compute to freeze for hours in certain scenarios.

This adds the same wrapping to libvirt calls which return lists of
virNodeDevice.

Closes-Bug: #2091033

Change-Id: I60d6f04d374e9ede5895a43b7a75e955b0fea3c5
(cherry picked from commit f304b9e)
  • Loading branch information
melwitt authored and priteau committed Jan 21, 2025
1 parent 5fc31aa commit 3c88b76
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 2 deletions.
42 changes: 42 additions & 0 deletions nova/tests/unit/virt/libvirt/test_host.py
Original file line number Diff line number Diff line change
Expand Up @@ -2152,6 +2152,48 @@ def test_tpool_list_all_connections(self):
self.assertIsInstance(domain, tpool.Proxy)
self.assertIn(domain.UUIDString(), (uuids.vm1, uuids.vm2))

def _add_fake_host_devices(self):
self.conn._obj.pci_info = fakelibvirt.HostPCIDevicesInfo(
num_pci=1, num_pfs=2, num_vfs=2, num_mdevcap=3)
mdevs = {
'mdev_4b20d080_1b54_4048_85b3_a6a62d165c01':
fakelibvirt.FakeMdevDevice(
dev_name='mdev_4b20d080_1b54_4048_85b3_a6a62d165c01',
type_id=fakelibvirt.NVIDIA_11_VGPU_TYPE,
parent=fakelibvirt.MDEVCAP_DEV1_PCI_ADDR),
}
self.conn._obj.mdev_info = fakelibvirt.HostMdevDevicesInfo(
devices=mdevs)

def test_tpool_list_all_devices(self):
self._add_fake_host_devices()
devs = self.host.list_all_devices(
fakelibvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_PCI_DEV)
self.assertEqual(8, len(devs))
for dev in devs:
self.assertIsInstance(dev, tpool.Proxy)

def test_tpool_list_pci_devices(self):
self._add_fake_host_devices()
devs = self.host.list_pci_devices()
self.assertEqual(8, len(devs))
for dev in devs:
self.assertIsInstance(dev, tpool.Proxy)

def test_tpool_list_mdev_capable_devices(self):
self._add_fake_host_devices()
devs = self.host.list_mdev_capable_devices()
self.assertEqual(3, len(devs))
for dev in devs:
self.assertIsInstance(dev, tpool.Proxy)

def test_tpool_list_mediated_devices(self):
self._add_fake_host_devices()
devs = self.host.list_mediated_devices()
self.assertEqual(1, len(devs))
for dev in devs:
self.assertIsInstance(dev, tpool.Proxy)


class LoadersTestCase(test.NoDBTestCase):

Expand Down
9 changes: 7 additions & 2 deletions nova/virt/libvirt/host.py
Original file line number Diff line number Diff line change
Expand Up @@ -1592,7 +1592,9 @@ def _list_devices(self, cap, flags=0):
:returns: a list of virNodeDevice instance
"""
try:
return self.get_connection().listDevices(cap, flags)
devs = [self._wrap_libvirt_proxy(dev)
for dev in self.get_connection().listDevices(cap, flags)]
return devs
except libvirt.libvirtError as ex:
error_code = ex.get_error_code()
if error_code == libvirt.VIR_ERR_NO_SUPPORT:
Expand All @@ -1612,7 +1614,10 @@ def list_all_devices(
:returns: a list of virNodeDevice xml strings.
"""
try:
return self.get_connection().listAllDevices(flags) or []
alldevs = [
self._wrap_libvirt_proxy(dev)
for dev in self.get_connection().listAllDevices(flags)] or []
return alldevs
except libvirt.libvirtError as ex:
LOG.warning(ex)
return []
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fixes:
- |
`Bug #2091033`_: Fixed calls to libvirt ``listDevices()`` and
``listAllDevices()`` from potentially blocking all other greenthreads
in ``nova-compute``. Under certain circumstances, it was possible for
the ``nova-compute`` service to freeze with all other greenthreads
blocked and unable to perform any other activities including logging.
This issue has been fixed by wrapping the libvirt ``listDevices()``
and ``listAllDevices()`` calls with ``eventlet.tpool.Proxy``.
.. _Bug #2091033: https://bugs.launchpad.net/nova/+bug/2091033

0 comments on commit 3c88b76

Please sign in to comment.