diff options
| author | Chris Behrens <cbehrens@codestud.com> | 2013-03-18 20:26:02 +0000 |
|---|---|---|
| committer | Chris Behrens <cbehrens@codestud.com> | 2013-03-18 20:26:02 +0000 |
| commit | f9a89b7065ff4a15bf7ce14a983e8934cd4710f4 (patch) | |
| tree | c0f673e404f87749cd0156be5776d9f43cb09ffe | |
| parent | f14cd697c005f946886f90f7af8379c58e062ed1 (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.py | 13 | ||||
| -rwxr-xr-x | nova/virt/xenapi/driver.py | 6 | ||||
| -rw-r--r-- | nova/virt/xenapi/vmops.py | 12 |
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) |
