diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index 5823f33251..eead31416a 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -20506,6 +20506,24 @@ class LibvirtSnapshotTests(_BaseSnapshotTests): self._test_snapshot(disk_format='qcow2', extra_properties=extra_properties) + @mock.patch.object(host.Host, 'get_guest') + @mock.patch.object(host.Host, 'write_instance_config') + def test_failing_domain_not_found(self, mock_write_config, mock_get_guest): + self.flags(disable_libvirt_livesnapshot=False, group='workarounds') + mock_dev = mock.Mock(spec=libvirt_guest.BlockDevice) + mock_guest = mock.Mock(spec=libvirt_guest.Guest) + mock_guest.get_power_state.return_value = power_state.RUNNING + mock_guest.get_block_device.return_value = mock_dev + mock_guest._domain = mock.Mock() + mock_get_guest.return_value = mock_guest + ex = fakelibvirt.make_libvirtError( + fakelibvirt.libvirtError, + "No such domain", + error_code=fakelibvirt.VIR_ERR_NO_DOMAIN) + mock_dev.rebase.side_effect = ex + self.assertRaises(exception.InstanceNotFound, self._test_snapshot, + disk_format='qcow2') + @mock.patch.object(rbd_utils, 'RBDDriver') @mock.patch.object(rbd_utils, 'rbd') def test_raw_with_rbd_clone(self, mock_rbd, mock_driver): diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index f1d54f7ea5..cef539d092 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -1965,6 +1965,20 @@ class LibvirtDriver(driver.ComputeDriver): root_disk.snapshot_extract(out_path, image_format) LOG.info("Snapshot extracted, beginning image upload", instance=instance) + except libvirt.libvirtError as ex: + error_code = ex.get_error_code() + if error_code == libvirt.VIR_ERR_NO_DOMAIN: + LOG.info('Instance %(instance_name)s disappeared ' + 'while taking snapshot of it: [Error Code ' + '%(error_code)s] %(ex)s', + {'instance_name': instance.name, + 'error_code': error_code, + 'ex': ex}, + instance=instance) + raise exception.InstanceNotFound( + instance_id=instance.uuid) + else: + raise finally: self._snapshot_domain(context, live_snapshot, virt_dom, state, instance)