From a5aa8e2eb8d5a90780211ef67b8f2dcc76af64de Mon Sep 17 00:00:00 2001 From: Sylvain Bauza Date: Wed, 25 Apr 2018 17:28:08 +0200 Subject: [PATCH] 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 8941c79f0924413822b15824a298e081e345e616) --- nova/tests/unit/virt/libvirt/test_driver.py | 9 +++++++++ nova/virt/libvirt/driver.py | 13 ++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index 8c1620b0741f..d7db2bbaaa0f 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -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': { diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index ed7915a1fa28..8c9b7339d158 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -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)