libvirt: fix hard reboot issue with mdevs

Sometimes, a Nova instance may not have an associated libvirt guest,
like if a live migration fails and the hypervisor on the source node
is in an inconsistent state.
The usual way to fix that is to hard reboot the instance, so the
virt driver recreates the guest.
Unfortunately, we introduced a regression in Queens with
Ie6c9108808a461359d717d8a9e9399c8a407bfe9 because we weren't
checking whether the guest was there or not.

This fix aims to catch the InstanceNotFound exception that's
raised and just tell there are no mediated devices attached to that
instance (given we can no longer know them).

Change-Id: Iff30e59ced63a94c5c3377317a2e2a502f96eb91
Closes-Bug: #1764460
(cherry picked from commit 8941c79f09)
This commit is contained in:
Sylvain Bauza 2018-04-25 17:28:08 +02:00 committed by Lee Yarwood
parent bf0a069773
commit a5aa8e2eb8
2 changed files with 21 additions and 1 deletions

View File

@ -19567,6 +19567,15 @@ class LibvirtDriverTestCase(test.NoDBTestCase):
drvr._get_all_assigned_mediated_devices(fake_inst))
get_guest.assert_called_once_with(fake_inst)
@mock.patch.object(host.Host, 'get_guest')
def test_get_all_assigned_mediated_devices_for_a_non_existing_instance(
self, get_guest):
get_guest.side_effect = exception.InstanceNotFound(instance_id='fake')
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
fake_inst = objects.Instance()
self.assertEqual({},
drvr._get_all_assigned_mediated_devices(fake_inst))
def test_allocate_mdevs_with_no_vgpu_allocations(self):
allocations = {
'rp1': {

View File

@ -6034,7 +6034,18 @@ class LibvirtDriver(driver.ComputeDriver):
"""
allocated_mdevs = {}
if instance:
guest = self._host.get_guest(instance)
# NOTE(sbauza): In some cases (like a migration issue), the
# instance can exist in the Nova database but libvirt doesn't know
# about it. For such cases, the way to fix that is to hard reboot
# the instance, which will recreate the libvirt guest.
# For that reason, we need to support that case by making sure
# we don't raise an exception if the libvirt guest doesn't exist.
try:
guest = self._host.get_guest(instance)
except exception.InstanceNotFound:
# Bail out early if libvirt doesn't know about it since we
# can't know the existing mediated devices
return {}
guests = [guest]
else:
guests = self._host.list_guests(only_running=False)