From 091a910576d9b580678f1881fffa425ab4632f48 Mon Sep 17 00:00:00 2001 From: Lee Yarwood Date: Thu, 25 Apr 2019 15:34:41 +0100 Subject: [PATCH] libvirt: Always disconnect volumes after libvirtError exceptions Building on Ib440f4f2e484312af5f393722363846f6c95b760 we should always attempt to disconnect volumes from the host when exceptions are thrown while attempting to attach a volume to a domain. This was previously done for generic exceptions but not for libvirtError exceptions. Closes-Bug: #1826523 Change-Id: If21230869826c992e7d0398434b9a4b255940213 --- nova/tests/unit/virt/libvirt/test_driver.py | 10 ++++++++-- nova/virt/libvirt/driver.py | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index 666cf97cee25..25a15f0b487c 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -7775,11 +7775,13 @@ class LibvirtConnTestCase(test.NoDBTestCase, mock.patch.object(drvr._host, 'get_guest'), mock.patch('nova.virt.libvirt.driver.LOG'), mock.patch.object(drvr, '_connect_volume'), + mock.patch.object(drvr, '_disconnect_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_disconnect_volume, mock_get_volume_config, + mock_check_discard, mock_build_metadata): mock_conf = mock.MagicMock() mock_guest = mock.MagicMock() @@ -7793,6 +7795,7 @@ class LibvirtConnTestCase(test.NoDBTestCase, self.context, connection_info, instance, "/dev/vdb", disk_bus=bdm['disk_bus'], device_type=bdm['device_type']) mock_log.warning.assert_called_once() + mock_disconnect_volume.assert_called_once() @mock.patch('nova.virt.libvirt.blockinfo.get_info_from_bdm') def test_attach_volume_with_libvirt_exception(self, mock_get_info): @@ -7814,11 +7817,13 @@ class LibvirtConnTestCase(test.NoDBTestCase, mock.patch.object(drvr._host, 'get_guest'), mock.patch('nova.virt.libvirt.driver.LOG'), mock.patch.object(drvr, '_connect_volume'), + mock.patch.object(drvr, '_disconnect_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_disconnect_volume, mock_get_volume_config, + mock_check_discard, mock_build_metadata): mock_conf = mock.MagicMock() mock_guest = mock.MagicMock() @@ -7833,6 +7838,7 @@ class LibvirtConnTestCase(test.NoDBTestCase, 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_disconnect_volume.assert_called_once() @mock.patch('nova.utils.get_image_from_system_metadata') @mock.patch('nova.virt.libvirt.blockinfo.get_info_from_bdm') diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index db81b292b56a..54df79679de5 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -1551,6 +1551,8 @@ class LibvirtDriver(driver.ComputeDriver): else: LOG.exception(_('Failed to attach volume at mountpoint: ' '%s'), mountpoint, instance=instance) + self._disconnect_volume(context, connection_info, instance, + encryption=encryption) except Exception: LOG.exception(_('Failed to attach volume at mountpoint: %s'), mountpoint, instance=instance)