diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index 369f3214ad8e..e4225a644cad 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -7794,6 +7794,46 @@ class LibvirtConnTestCase(test.NoDBTestCase, disk_bus=bdm['disk_bus'], device_type=bdm['device_type']) mock_log.warning.assert_called_once() + @mock.patch('nova.virt.libvirt.blockinfo.get_info_from_bdm') + def test_attach_volume_with_libvirt_exception(self, mock_get_info): + drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) + instance = objects.Instance(**self.test_instance) + connection_info = {"driver_volume_type": "fake", + "data": {"device_path": "/fake", + "access_mode": "rw"}} + bdm = {'device_name': 'vdb', + 'disk_bus': 'fake-bus', + 'device_type': 'fake-type'} + disk_info = {'bus': bdm['disk_bus'], 'type': bdm['device_type'], + 'dev': 'vdb'} + libvirt_exc = fakelibvirt.make_libvirtError(fakelibvirt.libvirtError, + "Target vdb already exists', device is busy", + error_code=fakelibvirt.VIR_ERR_INTERNAL_ERROR) + + with test.nested( + mock.patch.object(drvr._host, 'get_guest'), + mock.patch('nova.virt.libvirt.driver.LOG'), + mock.patch.object(drvr, '_connect_volume'), + mock.patch.object(drvr, '_get_volume_config'), + mock.patch.object(drvr, '_check_discard_for_attach_volume'), + mock.patch.object(drvr, '_build_device_metadata'), + ) as (mock_get_guest, mock_log, mock_connect_volume, + mock_get_volume_config, mock_check_discard, mock_build_metadata): + + mock_conf = mock.MagicMock() + mock_guest = mock.MagicMock() + mock_guest.attach_device.side_effect = libvirt_exc + mock_get_volume_config.return_value = mock_conf + mock_get_guest.return_value = mock_guest + mock_get_info.return_value = disk_info + mock_build_metadata.return_value = objects.InstanceDeviceMetadata() + + self.assertRaises(fakelibvirt.libvirtError, drvr.attach_volume, + self.context, connection_info, instance, "/dev/vdb", + disk_bus=bdm['disk_bus'], device_type=bdm['device_type']) + mock_log.exception.assert_called_once_with(u'Failed to attach ' + 'volume at mountpoint: %s', '/dev/vdb', instance=instance) + @mock.patch('nova.utils.get_image_from_system_metadata') @mock.patch('nova.virt.libvirt.blockinfo.get_info_from_bdm') @mock.patch('nova.virt.libvirt.host.Host._get_domain') diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index f0cbeac56e5a..7f1270042fc7 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -1514,11 +1514,15 @@ class LibvirtDriver(driver.ComputeDriver): # distributions provide Libvirt 3.3.0 or earlier with # https://libvirt.org/git/?p=libvirt.git;a=commit;h=7189099 applied. except libvirt.libvirtError as ex: - if 'Incorrect number of padding bytes' in six.text_type(ex): - LOG.warning(_('Failed to attach encrypted volume due to a ' - 'known Libvirt issue, see the following bug for details: ' - 'https://bugzilla.redhat.com/show_bug.cgi?id=1447297')) - raise + with excutils.save_and_reraise_exception(): + if 'Incorrect number of padding bytes' in six.text_type(ex): + LOG.warning(_('Failed to attach encrypted volume due to a ' + 'known Libvirt issue, see the following bug ' + 'for details: ' + 'https://bugzilla.redhat.com/1447297')) + else: + LOG.exception(_('Failed to attach volume at mountpoint: ' + '%s'), mountpoint, instance=instance) except Exception: LOG.exception(_('Failed to attach volume at mountpoint: %s'), mountpoint, instance=instance)