diff options
| author | Jenkins <jenkins@review.openstack.org> | 2012-09-29 01:54:55 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2012-09-29 01:54:55 +0000 |
| commit | 7104362abbee82b3d2adebdf5589f859c1b67279 (patch) | |
| tree | bbddbe6284d35641f139b21fda59eddca1f178a4 /nova/virt | |
| parent | 8e9a2ac7fe19ca8319b27b4cf779b255926033a0 (diff) | |
| parent | 8887f10c66bca248f289db8f834ae8f36f9a03a1 (diff) | |
Merge "Collect more accurate bandwidth data for XenServer"
Diffstat (limited to 'nova/virt')
| -rw-r--r-- | nova/virt/driver.py | 4 | ||||
| -rw-r--r-- | nova/virt/fake.py | 8 | ||||
| -rw-r--r-- | nova/virt/xenapi/driver.py | 28 | ||||
| -rw-r--r-- | nova/virt/xenapi/vm_utils.py | 9 | ||||
| -rw-r--r-- | nova/virt/xenapi/vmops.py | 41 |
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): |
