summaryrefslogtreecommitdiffstats
path: root/nova/virt
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-09-29 01:54:55 +0000
committerGerrit Code Review <review@openstack.org>2012-09-29 01:54:55 +0000
commit7104362abbee82b3d2adebdf5589f859c1b67279 (patch)
treebbddbe6284d35641f139b21fda59eddca1f178a4 /nova/virt
parent8e9a2ac7fe19ca8319b27b4cf779b255926033a0 (diff)
parent8887f10c66bca248f289db8f834ae8f36f9a03a1 (diff)
Merge "Collect more accurate bandwidth data for XenServer"
Diffstat (limited to 'nova/virt')
-rw-r--r--nova/virt/driver.py4
-rw-r--r--nova/virt/fake.py8
-rw-r--r--nova/virt/xenapi/driver.py28
-rw-r--r--nova/virt/xenapi/vm_utils.py9
-rw-r--r--nova/virt/xenapi/vmops.py41
5 files changed, 43 insertions, 47 deletions
diff --git a/nova/virt/driver.py b/nova/virt/driver.py
index 41df132fc..d741524b0 100644
--- a/nova/virt/driver.py
+++ b/nova/virt/driver.py
@@ -221,8 +221,8 @@ class ComputeDriver(object):
# TODO(Vek): Need to pass context in for access to auth_token
raise NotImplementedError()
- def get_all_bw_usage(self, instances, start_time, stop_time=None):
- """Return bandwidth usage info for each interface on each
+ def get_all_bw_counters(self, instances):
+ """Return bandwidth usage counters for each interface on each
running VM"""
raise NotImplementedError()
diff --git a/nova/virt/fake.py b/nova/virt/fake.py
index a6476f9d9..959ab174c 100644
--- a/nova/virt/fake.py
+++ b/nova/virt/fake.py
@@ -186,11 +186,11 @@ class FakeDriver(driver.ComputeDriver):
def get_diagnostics(self, instance_name):
return 'FAKE_DIAGNOSTICS'
- def get_all_bw_usage(self, instances, start_time, stop_time=None):
- """Return bandwidth usage info for each interface on each
+ def get_all_bw_counters(self, instances):
+ """Return bandwidth usage counters for each interface on each
running VM"""
- bwusage = []
- return bwusage
+ bw = []
+ return bw
def block_stats(self, instance_name, disk_id):
return [0L, 0L, 0L, 0L, None]
diff --git a/nova/virt/xenapi/driver.py b/nova/virt/xenapi/driver.py
index 3425c64f8..ad2d64a38 100644
--- a/nova/virt/xenapi/driver.py
+++ b/nova/virt/xenapi/driver.py
@@ -298,35 +298,27 @@ class XenAPIDriver(driver.ComputeDriver):
"""Return data about VM diagnostics"""
return self._vmops.get_diagnostics(instance)
- def get_all_bw_usage(self, instances, start_time, stop_time=None):
- """Return bandwidth usage info for each interface on each
+ def get_all_bw_counters(self, instances):
+ """Return bandwidth usage counters for each interface on each
running VM"""
# we only care about VMs that correspond to a nova-managed
# instance:
imap = dict([(inst.name, inst.uuid) for inst in instances])
-
- bwusage = []
- start_time = time.mktime(start_time.timetuple())
- if stop_time:
- stop_time = time.mktime(stop_time.timetuple())
+ bwcounters = []
# get a dictionary of instance names. values are dictionaries
- # of mac addresses with values that are the bw stats:
+ # of mac addresses with values that are the bw counters:
# e.g. {'instance-001' : { 12:34:56:78:90:12 : {'bw_in': 0, ....}}
- iusages = self._vmops.get_all_bw_usage(start_time, stop_time)
- for instance_name in iusages:
+ all_counters = self._vmops.get_all_bw_counters()
+ for instance_name, counters in all_counters.iteritems():
if instance_name in imap:
# yes these are stats for a nova-managed vm
# correlate the stats with the nova instance uuid:
- iusage = iusages[instance_name]
-
- for macaddr, usage in iusage.iteritems():
- bwusage.append(dict(mac_address=macaddr,
- uuid=imap[instance_name],
- bw_in=usage['bw_in'],
- bw_out=usage['bw_out']))
- return bwusage
+ for vif_counter in counters.values():
+ vif_counter['uuid'] = imap[instance_name]
+ bwcounters.append(vif_counter)
+ return bwcounters
def get_console_output(self, instance):
"""Return snapshot of console"""
diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py
index a9adb4575..2dc358f0f 100644
--- a/nova/virt/xenapi/vm_utils.py
+++ b/nova/virt/xenapi/vm_utils.py
@@ -1351,9 +1351,16 @@ def compile_diagnostics(record):
return {"Unable to retrieve diagnostics": e}
+def fetch_bandwidth(session):
+ bw = session.call_plugin_serialized('bandwidth', 'fetch_all_bandwidth')
+ return bw
+
+
def compile_metrics(start_time, stop_time=None):
"""Compile bandwidth usage, cpu, and disk metrics for all VMs on
- this host"""
+ this host.
+ Note that some stats, like bandwith, do not seem to be very
+ accurate in some of the data from XenServer (mdragon). """
start_time = int(start_time)
xml = _get_rrd_updates(_get_rrd_server(), start_time)
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index 3f14b98b9..cea5485ab 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -1208,34 +1208,31 @@ class VMOps(object):
vm_rec = self._session.call_xenapi("VM.get_record", vm_ref)
return vm_utils.compile_diagnostics(vm_rec)
- def get_all_bw_usage(self, start_time, stop_time=None):
- """Return bandwidth usage info for each interface on each
+ def _get_vif_device_map(self, vm_rec):
+ vif_map = {}
+ for vif in [self._session.call_xenapi("VIF.get_record", vrec)
+ for vrec in vm_rec['VIFs']]:
+ vif_map[vif['device']] = vif['MAC']
+ return vif_map
+
+ def get_all_bw_counters(self):
+ """Return running bandwidth counter for each interface on each
running VM"""
- try:
- metrics = vm_utils.compile_metrics(start_time, stop_time)
- except exception.CouldNotFetchMetrics:
- LOG.exception(_("Could not get bandwidth info."))
- return {}
+ counters = vm_utils.fetch_bandwidth(self._session)
bw = {}
- for uuid, data in metrics.iteritems():
- vm_ref = self._session.call_xenapi("VM.get_by_uuid", uuid)
- vm_rec = self._session.call_xenapi("VM.get_record", vm_ref)
- vif_map = {}
- for vif in [self._session.call_xenapi("VIF.get_record", vrec)
- for vrec in vm_rec['VIFs']]:
- vif_map[vif['device']] = vif['MAC']
+ for vm_ref, vm_rec in vm_utils.list_vms(self._session):
+ vif_map = self._get_vif_device_map(vm_rec)
name = vm_rec['name_label']
if 'nova_uuid' not in vm_rec['other_config']:
continue
+ dom = vm_rec.get('domid')
+ if dom is None or dom not in counters:
+ continue
vifs_bw = bw.setdefault(name, {})
- for key, val in data.iteritems():
- if key.startswith('vif_'):
- vname = key.split('_')[1]
- vif_bw = vifs_bw.setdefault(vif_map[vname], {})
- if key.endswith('tx'):
- vif_bw['bw_out'] = int(val)
- if key.endswith('rx'):
- vif_bw['bw_in'] = int(val)
+ for vif_num, vif_data in counters[dom].iteritems():
+ mac = vif_map[vif_num]
+ vif_data['mac_address'] = mac
+ vifs_bw[mac] = vif_data
return bw
def get_console_output(self, instance):