summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Behrens <cbehrens@codestud.com>2013-03-18 20:26:02 +0000
committerChris Behrens <cbehrens@codestud.com>2013-03-18 20:26:02 +0000
commitf9a89b7065ff4a15bf7ce14a983e8934cd4710f4 (patch)
treec0f673e404f87749cd0156be5776d9f43cb09ffe
parentf14cd697c005f946886f90f7af8379c58e062ed1 (diff)
Fix XenAPI performance issue
This patch implements 'list_instance_uuids' in the xenapi virt driver so that compute manager's '_get_instances_on_driver' can operate more efficiently. Fixes bug 1097980 The cleanup_running_deleted_instances periodic task uses the above call while context has been modified to be read_deleted='yes'. Without list_instance_uuids being implemented in xenapi, there's a fallback to querying all instances on the host. Because of read_deleted='yes', this queries all instances that have ever lived on the host. In a very busy environment where instances are repeatedly built and destroyed, one can end up with thousands of deleted instances. Now that we are storing instance_type data in system_metadata and system_metadata is joined with every instance_get, this results in 10x the number of rows being returned with sqlalchemy... the fallback doesn't perform well enough. Change-Id: I4bbfd69c9769807cec813af757665f03d9643460
-rw-r--r--nova/tests/test_xenapi.py13
-rwxr-xr-xnova/virt/xenapi/driver.py6
-rw-r--r--nova/virt/xenapi/vmops.py12
3 files changed, 31 insertions, 0 deletions
diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py
index 6714161f1..330a229ab 100644
--- a/nova/tests/test_xenapi.py
+++ b/nova/tests/test_xenapi.py
@@ -374,6 +374,19 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
instances = self.conn.list_instances()
self.assertEquals(instances, [])
+ def test_list_instance_uuids_0(self):
+ instance_uuids = self.conn.list_instance_uuids()
+ self.assertEquals(instance_uuids, [])
+
+ def test_list_instance_uuids(self):
+ uuids = []
+ for x in xrange(1, 4):
+ instance = self._create_instance(x)
+ uuids.append(instance['uuid'])
+ instance_uuids = self.conn.list_instance_uuids()
+ self.assertEqual(len(uuids), len(instance_uuids))
+ self.assertEqual(set(uuids), set(instance_uuids))
+
def test_get_rrd_server(self):
self.flags(xenapi_connection_url='myscheme://myaddress/')
server_info = vm_utils._get_rrd_server()
diff --git a/nova/virt/xenapi/driver.py b/nova/virt/xenapi/driver.py
index 302679685..86b486b97 100755
--- a/nova/virt/xenapi/driver.py
+++ b/nova/virt/xenapi/driver.py
@@ -164,6 +164,12 @@ class XenAPIDriver(driver.ComputeDriver):
"""List VM instances."""
return self._vmops.list_instances()
+ def list_instance_uuids(self):
+ """Get the list of nova instance uuids for VMs found on the
+ hypervisor.
+ """
+ return self._vmops.list_instance_uuids()
+
def spawn(self, context, instance, image_meta, injected_files,
admin_password, network_info=None, block_device_info=None):
"""Create VM instance."""
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index cd7311678..4fa978936 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -190,6 +190,18 @@ class VMOps(object):
return name_labels
+ def list_instance_uuids(self):
+ """Get the list of nova instance uuids for VMs found on the
+ hypervisor.
+ """
+ nova_uuids = []
+ for vm_ref, vm_rec in vm_utils.list_vms(self._session):
+ other_config = vm_rec['other_config']
+ nova_uuid = other_config.get('nova_uuid')
+ if nova_uuid:
+ nova_uuids.append(nova_uuid)
+ return nova_uuids
+
def confirm_migration(self, migration, instance, network_info):
name_label = self._get_orig_vm_name_label(instance)
vm_ref = vm_utils.lookup(self._session, name_label)