From be83c7ecc09fac5ef88e6624c9e026bf730a5ff3 Mon Sep 17 00:00:00 2001 From: Lee Yarwood Date: Fri, 20 Jul 2018 16:02:49 +0100 Subject: [PATCH] libvirt: Remove reference to transient domain when detaching devices When detaching a device from a domain we first attempt to remove the device from both the persistent and live configs before looping to ensure the device has really been detached from the running live config. Previously when this failed we logged an error message that suggested that this was due to issues detaching the device from a transient domain, however this is not the case as the domain is persistent. This change simply updates the error and associated comments to only reference the live config of the domain. Additionally a DEBUG line claiming that a device has been successfully detached is now only logged once the device is removed from the live config, hopefully avoiding any confusion from this line been logged each time an attempt is made to detach the device. Change-Id: If869470216600c303d47cf79f12c4fc88abcf813 (cherry picked from commit 636c7461dee4002571da6e99986eb17e9a28b0f4) --- nova/tests/unit/virt/libvirt/test_driver.py | 7 ++++--- nova/tests/unit/virt/libvirt/test_guest.py | 6 +++--- nova/virt/libvirt/guest.py | 14 ++++++++------ 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index e5c85a54aa56..06ecc41185a2 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -7450,7 +7450,8 @@ class LibvirtConnTestCase(test.NoDBTestCase, mock_dom = mock.MagicMock() # Second time don't return anything about disk vdc so it looks removed - return_list = [mock_xml_with_disk, mock_xml_without_disk] + return_list = [mock_xml_with_disk, mock_xml_without_disk, + mock_xml_without_disk] # Doubling the size of return list because we test with two guest power # states mock_dom.XMLDesc.side_effect = return_list + return_list @@ -18950,7 +18951,7 @@ class LibvirtDriverTestCase(test.NoDBTestCase): # DeviceNotFound get_interface_calls = [expected_cfg, None] else: - get_interface_calls = [expected_cfg, expected_cfg, None] + get_interface_calls = [expected_cfg, expected_cfg, None, None] with test.nested( mock.patch.object(host.Host, 'get_guest', return_value=guest), @@ -19087,7 +19088,7 @@ class LibvirtDriverTestCase(test.NoDBTestCase): domain.detachDeviceFlags(expected.to_xml(), flags=expected_flags) self.mox.ReplayAll() with mock.patch.object(libvirt_guest.Guest, 'get_interface_by_cfg', - side_effect=[expected, expected, None]): + side_effect=[expected, expected, None, None]): self.drvr.detach_interface(self.context, instance, network_info[0]) self.mox.VerifyAll() diff --git a/nova/tests/unit/virt/libvirt/test_guest.py b/nova/tests/unit/virt/libvirt/test_guest.py index 7c61334a5a18..70299dfe1ee3 100644 --- a/nova/tests/unit/virt/libvirt/test_guest.py +++ b/nova/tests/unit/virt/libvirt/test_guest.py @@ -228,7 +228,7 @@ class GuestTestCase(test.NoDBTestCase): conf = mock.Mock(spec=vconfig.LibvirtConfigGuestDevice) conf.to_xml.return_value = "" get_config = mock.Mock() - get_config.side_effect = [conf, conf, None] + get_config.side_effect = [conf, conf, conf, None, None] dev_path = "/dev/vdb" self.domain.isPersistent.return_value = False retry_detach = self.guest.detach_device_with_retry( @@ -244,7 +244,7 @@ class GuestTestCase(test.NoDBTestCase): conf.to_xml.return_value = "" get_config = mock.Mock() # Force multiple retries of detach - get_config.side_effect = [conf, conf, conf, None] + get_config.side_effect = [conf, conf, conf, conf, conf, None, None] dev_path = "/dev/vdb" self.domain.isPersistent.return_value = True @@ -356,7 +356,7 @@ class GuestTestCase(test.NoDBTestCase): get_config = mock.Mock() # Simulate the persistent domain attach attempt followed by the live # domain attach attempt and success - get_config.side_effect = [conf, conf, None] + get_config.side_effect = [conf, conf, conf, None, None] fake_device = "vdb" fake_exc = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "", diff --git a/nova/virt/libvirt/guest.py b/nova/virt/libvirt/guest.py index 86e9aa051b9c..573d800bf714 100644 --- a/nova/virt/libvirt/guest.py +++ b/nova/virt/libvirt/guest.py @@ -398,9 +398,11 @@ class Guest(object): # Raise DeviceNotFound if the device isn't found during detach try: self.detach_device(conf, persistent=persistent, live=live) - LOG.debug('Successfully detached device %s from guest. ' - 'Persistent? %s. Live? %s', - device, persistent, live) + if get_device_conf_func(device) is None: + LOG.debug('Successfully detached device %s from guest. ' + 'Persistent? %s. Live? %s', + device, persistent, live) + except libvirt.libvirtError as ex: with excutils.save_and_reraise_exception(): errcode = ex.get_error_code() @@ -452,11 +454,11 @@ class Guest(object): def _do_wait_and_retry_detach(): config = get_device_conf_func(device) if config is not None: - # Device is already detached from persistent domain - # and only transient domain needs update + # Device is already detached from persistent config + # and only the live config needs to be updated. _try_detach_device(config, persistent=False, live=live) - reason = _("Unable to detach from guest transient domain.") + reason = _("Unable to detach the device from the live config.") raise exception.DeviceDetachFailed( device=alternative_device_name, reason=reason)