From f97f6214dac7951cb4d91bf24e9ceb3a43e65938 Mon Sep 17 00:00:00 2001 From: Stanislaw Pitucha Date: Mon, 11 Mar 2013 17:54:47 +0000 Subject: Handle vcpu counting failures gracefully The virDomainGetVcpus() call in libvirt can fail in some cases. This should be handled properly in nova and not cause failures in starting up new instances. Fixes bug 1153694 Change-Id: I8e072c53ee2bafcb50083d793ceabe5292038ab6 --- nova/tests/test_libvirt.py | 29 +++++++++++++++++++++++++++++ nova/virt/libvirt/driver.py | 6 +++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py index 55b6aaec4..3e379a292 100644 --- a/nova/tests/test_libvirt.py +++ b/nova/tests/test_libvirt.py @@ -3532,6 +3532,35 @@ class LibvirtConnTestCase(test.TestCase): } self.assertEqual(actual, expect) + def test_failing_vcpu_count(self): + """Domain can fail to return the vcpu description in case it's + just starting up or shutting down. Make sure None is handled + gracefully. + """ + + class DiagFakeDomain(object): + def __init__(self, vcpus): + self._vcpus = vcpus + + def vcpus(self): + if self._vcpus is None: + return None + else: + return ([1] * self._vcpus, [True] * self._vcpus) + + driver = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) + conn = driver._conn + self.mox.StubOutWithMock(driver, 'list_instance_ids') + self.mox.StubOutWithMock(conn, 'lookupByID') + + driver.list_instance_ids().AndReturn([1, 2]) + conn.lookupByID(1).AndReturn(DiagFakeDomain(None)) + conn.lookupByID(2).AndReturn(DiagFakeDomain(5)) + + self.mox.ReplayAll() + + self.assertEqual(5, driver.get_vcpu_used()) + def test_get_instance_capabilities(self): conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 5e6b0e742..e7e6b716f 100755 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -2563,7 +2563,11 @@ class LibvirtDriver(driver.ComputeDriver): try: dom = self._conn.lookupByID(dom_id) vcpus = dom.vcpus() - total += len(vcpus[1]) + if vcpus is None: + LOG.debug(_("couldn't obtain the vpu count from domain id:" + " %s") % dom_id) + else: + total += len(vcpus[1]) except libvirt.libvirtError as err: if err.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN: LOG.debug(_("List of domains returned by libVirt: %s") -- cgit