From 68b9934baa6badc6fa35af0500c2b79220099428 Mon Sep 17 00:00:00 2001 From: Sean Mooney Date: Tue, 21 May 2024 17:53:07 +0100 Subject: [PATCH] add functional repoducer for bug 2065927 Today if the write sys call to offline a cpu when deleting an instnace fails due to an OSERROR or ValueERROR the instance delete fails and the instance goes to error. as reported in bug: #2065927 this can happen as a result of OSError: [Errno 16] Device or resource busy if the vm is deleted shortly after its started. Related-Bug: #2065927 Change-Id: I1352a3a1e28cfe14ec8f32042ed35cb25e70338e (cherry picked from commit ee581a5c9d1c0b7c0d8830a08f55fe8bc2fbcd0f) (cherry picked from commit f1c46802b109db0b8e62f461ef0b432fa7c0984e) (cherry picked from commit 254ea7bbfa697a717d8c1512d9c33e67b1f57ac9) --- .../functional/libvirt/test_power_manage.py | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/nova/tests/functional/libvirt/test_power_manage.py b/nova/tests/functional/libvirt/test_power_manage.py index f6e4b1ba5b42..d707168778b5 100644 --- a/nova/tests/functional/libvirt/test_power_manage.py +++ b/nova/tests/functional/libvirt/test_power_manage.py @@ -10,15 +10,16 @@ # License for the specific language governing permissions and limitations # under the License. -from unittest import mock - import fixtures +from unittest import mock + from nova import context as nova_context from nova import exception from nova import objects from nova.tests import fixtures as nova_fixtures from nova.tests.fixtures import libvirt as fakelibvirt +from nova.tests.functional.api import client from nova.tests.functional.libvirt import base from nova.virt import hardware from nova.virt.libvirt.cpu import api as cpu_api @@ -240,7 +241,6 @@ class PowerManagementTests(PowerManagementTestsBase): cpu_cores=5, cpu_threads=2) self.compute1 = self.start_compute(host_info=self.host_info, hostname='compute1') - # All cores are shutdown at startup, let's check. cpu_dedicated_set = hardware.get_cpu_dedicated_set() self._assert_cpu_set_state(cpu_dedicated_set, expected='offline') @@ -266,6 +266,33 @@ class PowerManagementTests(PowerManagementTestsBase): cpu_dedicated_set = hardware.get_cpu_dedicated_set() unused_cpus = cpu_dedicated_set - instance_pcpus self._assert_cpu_set_state(unused_cpus, expected='offline') + return server + + def test_delete_server(self): + server = self.test_create_server() + self._delete_server(server) + # Let's verify that the pinned CPUs are now offline + cpu_dedicated_set = hardware.get_cpu_dedicated_set() + self._assert_cpu_set_state(cpu_dedicated_set, expected='offline') + + def test_delete_server_device_busy(self): + server = self.test_create_server() + + inst = objects.Instance.get_by_uuid(self.ctxt, server['id']) + instance_pcpus = inst.numa_topology.cpu_pinning + self._assert_cpu_set_state(instance_pcpus, expected='online') + with mock.patch( + 'nova.filesystem.write_sys', + side_effect=exception.FileNotFound(file_path='fake')): + # This is bug 2065927 + self.assertRaises( + client.OpenStackApiException, self._delete_server, server) + cpu_dedicated_set = hardware.get_cpu_dedicated_set() + # Verify that the unused CPUs are still offline + unused_cpus = cpu_dedicated_set - instance_pcpus + self._assert_cpu_set_state(unused_cpus, expected='offline') + # but the instance cpus are still online + self._assert_cpu_set_state(instance_pcpus, expected='online') def test_create_server_with_emulator_threads_isolate(self): server = self._create_server(