summaryrefslogtreecommitdiffstats
path: root/nova/virt
diff options
context:
space:
mode:
authorBrian Elliott <brian.elliott@rackspace.com>2012-06-21 04:25:24 +0000
committerBrian Elliott <brian.elliott@rackspace.com>2012-08-20 15:46:53 +0000
commitc7d812a35bf4ef42907366c3f674fd623cd46905 (patch)
treecc0cb8ac745d1fae51dafe7c24f499d5b0b27ea8 /nova/virt
parent740e93aae891d6c20f38b091ad9f54d71db0d7f7 (diff)
Keep the ComputeNode model updated with usage
Keep the compute host's ComputeNode model in sync with the level of resource usage. This enables the ComputeNode model to be used as a basis for scheduling decisions rather than forcing scheduler to calculate free resources from an instance_get_all on each request. Resources like memory and disk are claimed as instances are built or deleted. There is also support for configurable compute node stats (a generic key/value store) for extensible advertising of other usage stats that may be useful for a particular scheduler implementation. Additionally, there is a periodic task on the compute host that audits actual resource consumption at the virt layer to ensure that the database stays in sync. This change partially implements blueprint: scheduler-resource-race This patch complements: https://review.openstack.org/#/c/9540/ (build re-scheduling support) Change-Id: Ibbe3839a054f8b80664b413d47f766ca8d68e3f2
Diffstat (limited to 'nova/virt')
-rw-r--r--nova/virt/baremetal/driver.py23
-rw-r--r--nova/virt/driver.py10
-rw-r--r--nova/virt/fake.py20
-rw-r--r--nova/virt/libvirt/driver.py25
-rw-r--r--nova/virt/vmwareapi/driver.py2
-rw-r--r--nova/virt/xenapi/driver.py27
-rw-r--r--nova/virt/xenapi/fake.py2
-rw-r--r--nova/virt/xenapi/host.py3
8 files changed, 27 insertions, 85 deletions
diff --git a/nova/virt/baremetal/driver.py b/nova/virt/baremetal/driver.py
index 9fcdf4eb2..d92688276 100644
--- a/nova/virt/baremetal/driver.py
+++ b/nova/virt/baremetal/driver.py
@@ -659,22 +659,13 @@ class BareMetalDriver(driver.ComputeDriver):
# Bare metal doesn't currently support security groups
pass
- def update_available_resource(self, ctxt, host):
+ def get_available_resource(self):
"""Updates compute manager resource info on ComputeNode table.
This method is called when nova-coompute launches, and
whenever admin executes "nova-manage service update_resource".
-
- :param ctxt: security context
- :param host: hostname that compute manager is currently running
-
"""
- try:
- service_ref = db.service_get_all_compute_by_host(ctxt, host)[0]
- except exception.NotFound:
- raise exception.ComputeServiceUnavailable(host=host)
-
# Updating host information
dic = {'vcpus': self.get_vcpu_total(),
'memory_mb': self.get_memory_mb_total(),
@@ -685,18 +676,10 @@ class BareMetalDriver(driver.ComputeDriver):
'hypervisor_type': self.get_hypervisor_type(),
'hypervisor_version': self.get_hypervisor_version(),
'cpu_info': self.get_cpu_info(),
- 'cpu_arch': FLAGS.cpu_arch,
- 'service_id': service_ref['id']}
+ 'cpu_arch': FLAGS.cpu_arch}
- compute_node_ref = service_ref['compute_node']
LOG.info(_('#### RLK: cpu_arch = %s ') % FLAGS.cpu_arch)
- if not compute_node_ref:
- LOG.info(_('Compute_service record created for %s ') % host)
- dic['service_id'] = service_ref['id']
- db.compute_node_create(ctxt, dic)
- else:
- LOG.info(_('Compute_service record updated for %s ') % host)
- db.compute_node_update(ctxt, compute_node_ref[0]['id'], dic)
+ return dic
def ensure_filtering_rules_for_instance(self, instance_ref, network_info):
raise NotImplementedError()
diff --git a/nova/virt/driver.py b/nova/virt/driver.py
index dd3646bc9..1d8f94e9d 100644
--- a/nova/virt/driver.py
+++ b/nova/virt/driver.py
@@ -325,15 +325,13 @@ class ComputeDriver(object):
"""Power on the specified instance"""
raise NotImplementedError()
- def update_available_resource(self, ctxt, host):
- """Updates compute manager resource info on ComputeNode table.
+ def get_available_resource(self):
+ """Retrieve resource information.
This method is called when nova-compute launches, and
- whenever admin executes "nova-manage service update_resource".
-
- :param ctxt: security context
- :param host: hostname that compute manager is currently running
+ as part of a periodic task
+ :returns: Dictionary describing resources
"""
raise NotImplementedError()
diff --git a/nova/virt/fake.py b/nova/virt/fake.py
index dd20b0b15..db7f3a6ff 100644
--- a/nova/virt/fake.py
+++ b/nova/virt/fake.py
@@ -221,19 +221,13 @@ class FakeDriver(driver.ComputeDriver):
def refresh_provider_fw_rules(self):
pass
- def update_available_resource(self, ctxt, host):
+ def get_available_resource(self):
"""Updates compute manager resource info on ComputeNode table.
Since we don't have a real hypervisor, pretend we have lots of
disk and ram.
"""
- try:
- service_ref = db.service_get_all_compute_by_host(ctxt, host)[0]
- except exception.NotFound:
- raise exception.ComputeServiceUnavailable(host=host)
-
- # Updating host information
dic = {'vcpus': 1,
'memory_mb': 4096,
'local_gb': 1028,
@@ -242,16 +236,8 @@ class FakeDriver(driver.ComputeDriver):
'local_gb_used': 0,
'hypervisor_type': 'fake',
'hypervisor_version': '1.0',
- 'service_id': service_ref['id'],
- 'cpu_info': '?'}
-
- compute_node_ref = service_ref['compute_node']
- if not compute_node_ref:
- LOG.info(_('Compute_service record created for %s ') % host)
- db.compute_node_create(ctxt, dic)
- else:
- LOG.info(_('Compute_service record updated for %s ') % host)
- db.compute_node_update(ctxt, compute_node_ref[0]['id'], dic)
+ 'cpu_info': '?'}
+ return dic
def ensure_filtering_rules_for_instance(self, instance_ref, network_info):
"""This method is supported only by libvirt."""
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
index 1e2706841..adc0c8c7b 100644
--- a/nova/virt/libvirt/driver.py
+++ b/nova/virt/libvirt/driver.py
@@ -2173,23 +2173,14 @@ class LibvirtDriver(driver.ComputeDriver):
def refresh_provider_fw_rules(self):
self.firewall_driver.refresh_provider_fw_rules()
- def update_available_resource(self, ctxt, host):
- """Updates compute manager resource info on ComputeNode table.
+ def get_available_resource(self):
+ """Retrieve resource info.
This method is called as a periodic task and is used only
in live migration currently.
- :param ctxt: security context
- :param host: hostname that compute manager is currently running
-
+ :returns: dictionary containing resource info
"""
-
- try:
- service_ref = db.service_get_all_compute_by_host(ctxt, host)[0]
- except exception.NotFound:
- raise exception.ComputeServiceUnavailable(host=host)
-
- # Updating host information
dic = {'vcpus': self.get_vcpu_total(),
'memory_mb': self.get_memory_mb_total(),
'local_gb': self.get_local_gb_total(),
@@ -2200,16 +2191,8 @@ class LibvirtDriver(driver.ComputeDriver):
'hypervisor_version': self.get_hypervisor_version(),
'hypervisor_hostname': self.get_hypervisor_hostname(),
'cpu_info': self.get_cpu_info(),
- 'service_id': service_ref['id'],
'disk_available_least': self.get_disk_available_least()}
-
- compute_node_ref = service_ref['compute_node']
- if not compute_node_ref:
- LOG.info(_('Compute_service record created for %s ') % host)
- db.compute_node_create(ctxt, dic)
- else:
- LOG.info(_('Compute_service record updated for %s ') % host)
- db.compute_node_update(ctxt, compute_node_ref[0]['id'], dic)
+ return dic
def check_can_live_migrate_destination(self, ctxt, instance_ref,
block_migration=False,
diff --git a/nova/virt/vmwareapi/driver.py b/nova/virt/vmwareapi/driver.py
index 947bd3422..98d5dc306 100644
--- a/nova/virt/vmwareapi/driver.py
+++ b/nova/virt/vmwareapi/driver.py
@@ -196,7 +196,7 @@ class VMWareESXDriver(driver.ComputeDriver):
'username': FLAGS.vmwareapi_host_username,
'password': FLAGS.vmwareapi_host_password}
- def update_available_resource(self, ctxt, host):
+ def get_available_resource(self):
"""This method is supported only by libvirt."""
return
diff --git a/nova/virt/xenapi/driver.py b/nova/virt/xenapi/driver.py
index 3709c13af..6eb39e2b7 100644
--- a/nova/virt/xenapi/driver.py
+++ b/nova/virt/xenapi/driver.py
@@ -372,26 +372,22 @@ class XenAPIDriver(driver.ComputeDriver):
'username': FLAGS.xenapi_connection_username,
'password': FLAGS.xenapi_connection_password}
- def update_available_resource(self, ctxt, host):
- """Updates compute manager resource info on ComputeNode table.
+ def get_available_resource(self):
+ """Retrieve resource info.
This method is called when nova-compute launches, and
- whenever admin executes "nova-manage service update_resource".
+ as part of a periodic task.
- :param ctxt: security context
- :param host: hostname that compute manager is currently running
+ :returns: dictionary describing resources
"""
- try:
- service_ref = db.service_get_all_compute_by_host(ctxt, host)[0]
- except exception.NotFound:
- raise exception.ComputeServiceUnavailable(host=host)
-
host_stats = self.get_host_stats(refresh=True)
# Updating host information
total_ram_mb = host_stats['host_memory_total'] / (1024 * 1024)
- free_ram_mb = host_stats['host_memory_free'] / (1024 * 1024)
+ # NOTE(belliott) memory-free-computed is a value provided by XenServer
+ # for gauging free memory more conservatively than memory-free.
+ free_ram_mb = host_stats['host_memory_free_computed'] / (1024 * 1024)
total_disk_gb = host_stats['disk_total'] / (1024 * 1024 * 1024)
used_disk_gb = host_stats['disk_used'] / (1024 * 1024 * 1024)
@@ -404,16 +400,9 @@ class XenAPIDriver(driver.ComputeDriver):
'hypervisor_type': 'xen',
'hypervisor_version': 0,
'hypervisor_hostname': host_stats['host_hostname'],
- 'service_id': service_ref['id'],
'cpu_info': host_stats['host_cpu_info']['cpu_count']}
- compute_node_ref = service_ref['compute_node']
- if not compute_node_ref:
- LOG.info(_('Compute_service record created for %s ') % host)
- db.compute_node_create(ctxt, dic)
- else:
- LOG.info(_('Compute_service record updated for %s ') % host)
- db.compute_node_update(ctxt, compute_node_ref[0]['id'], dic)
+ return dic
def ensure_filtering_rules_for_instance(self, instance_ref, network_info):
# NOTE(salvatore-orlando): it enforces security groups on
diff --git a/nova/virt/xenapi/fake.py b/nova/virt/xenapi/fake.py
index 1f8e400c8..7cb6b5f59 100644
--- a/nova/virt/xenapi/fake.py
+++ b/nova/virt/xenapi/fake.py
@@ -254,6 +254,7 @@ def create_local_srs():
other_config={'i18n-original-value-name_label':
'Local storage',
'i18n-key': 'local-storage'},
+ physical_size=40000,
physical_utilisation=20000,
virtual_allocation=10000,
host_ref=host_ref)
@@ -262,6 +263,7 @@ def create_local_srs():
other_config={'i18n-original-value-name_label':
'Local storage ISO',
'i18n-key': 'local-storage-iso'},
+ physical_size=80000,
physical_utilisation=40000,
virtual_allocation=80000,
host_ref=host_ref)
diff --git a/nova/virt/xenapi/host.py b/nova/virt/xenapi/host.py
index b45a9106c..9db708925 100644
--- a/nova/virt/xenapi/host.py
+++ b/nova/virt/xenapi/host.py
@@ -155,8 +155,9 @@ class HostState(object):
# No SR configured
LOG.error(_("Unable to get SR for this host: %s") % e)
return
+ self._session.call_xenapi("SR.scan", sr_ref)
sr_rec = self._session.call_xenapi("SR.get_record", sr_ref)
- total = int(sr_rec["virtual_allocation"])
+ total = int(sr_rec["physical_size"])
used = int(sr_rec["physical_utilisation"])
data["disk_total"] = total
data["disk_used"] = used