Francesco Romani has uploaded a new change for review. Change subject: vm: drop now unused code ......................................................................
vm: drop now unused code Drop VmStatsThread, since it was replaced and it is now useless. Change-Id: Ic62c3251b770c41b48ff6823f26bbba8d8801903 Signed-off-by: Francesco Romani <[email protected]> --- M vdsm/virt/vm.py 1 file changed, 0 insertions(+), 513 deletions(-) git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/97/37597/1 diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py index 9f54075..fc49057 100644 --- a/vdsm/virt/vm.py +++ b/vdsm/virt/vm.py @@ -53,7 +53,6 @@ import caps import hooks import supervdsm -import numaUtils # local package imports from .domain_descriptor import DomainDescriptor @@ -69,7 +68,6 @@ from .vmtune import io_tune_values_to_dom, io_tune_dom_to_values from . import vmxml -from .sampling import AdvancedStatsFunction, AdvancedStatsThread from .utils import isVdsmImage from vmpowerdown import VmShutdown, VmReboot @@ -169,517 +167,6 @@ VolumeChainEntry = namedtuple('VolumeChainEntry', ['uuid', 'path', 'allocation']) - - -class VmStatsThread(AdvancedStatsThread): - MBPS_TO_BPS = 10 ** 6 / 8 - - # This flag will prevent excessive log flooding when running - # on libvirt with no support for metadata xml elements. - # - # The issue currently exists only on CentOS/RHEL 6.5 that - # ships libvirt-0.10.x. - # - # TODO: Remove as soon as there is a hard dependency we can use - _libvirt_metadata_supported = True - - def __init__(self, vm): - AdvancedStatsThread.__init__(self, log=vm.log, daemon=True) - self._vm = vm - - self.highWrite = ( - AdvancedStatsFunction( - self._highWrite, - config.getint('vars', 'vm_watermark_interval'))) - - self.sampleCpu = ( - AdvancedStatsFunction( - self._sampleCpu, - config.getint('vars', 'vm_sample_cpu_interval'), - config.getint('vars', 'vm_sample_cpu_window'))) - self.sampleDisk = ( - AdvancedStatsFunction( - self._sampleDisk, - config.getint('vars', 'vm_sample_disk_interval'), - config.getint('vars', 'vm_sample_disk_window'))) - self.sampleNet = ( - AdvancedStatsFunction( - self._sampleNet, - config.getint('vars', 'vm_sample_net_interval'), - config.getint('vars', 'vm_sample_net_window'))) - self.sampleBalloon = ( - AdvancedStatsFunction( - self._sampleBalloon, - config.getint('vars', 'vm_sample_balloon_interval'), 1)) - self.sampleVcpuPinning = ( - AdvancedStatsFunction( - self._sampleVcpuPinning, - config.getint('vars', 'vm_sample_vcpu_pin_interval'), 1)) - self.sampleCpuTune = ( - AdvancedStatsFunction( - self._sampleCpuTune, - config.getint('vars', 'vm_sample_cpu_tune_interval'), 1)) - - self.addStatsFunction( - self.highWrite, self.sampleCpu, - self.sampleDisk, self.sampleNet, self.sampleBalloon, - self.sampleVcpuPinning, self.sampleCpuTune) - - def _highWrite(self): - if not self._vm.isDisksStatsCollectionEnabled(): - # Avoid queries from storage during recovery process - return - self._vm.extendDrivesIfNeeded() - - def _sampleCpu(self): - """ - Physical CPU statistics. Return value is a dict with - at least three key/value pairs: - * 'cpu_time': total wall clock time spent, nanoseconds. - * 'system_time': time spent by the hypervisor in kernel - space, nanoseconds. - * 'user_time': time spent by the hypervisor in user space, - nanoseconds. - Extra keys will be ignored. - - Example: - { - 'cpu_time': 17732877847L, - 'system_time': 3030000000L, - 'user_time': 510000000L - } - """ - cpuStats = self._vm._dom.getCPUStats(True, 0) - return cpuStats[0] - - def _sampleDisk(self): - """ - Disk statistics. Return value is a dict with a key for - each Vm drive. Each value is in turn a dict with at least - eight key/value pairs: - * {rd,wr,flush}_total_times: total time spent, in the - I/O operations of the given kind, nanoseconds. - * {rd,wr,flush}_operations: number of operations of the given kind - * {rd,wr}_bytes: amount of bytes read or written, per disk. - Extra keys will be ignored. - - Example: - { - 'vda': - { - 'rd_total_times': 41725620156L, - 'wr_total_times': 11113038027L, - 'flush_total_times': 14947030448L, - 'rd_operations': 8395L, - 'wr_operations': 1174L, - 'flush_operations': 143L, - 'rd_bytes': 229022208L, - 'wr_bytes': 16778240L - } - } - """ - if not self._vm.isDisksStatsCollectionEnabled(): - # Avoid queries from storage during recovery process - return - - # The usage of the cryptic flag VIR_TYPED_PARAM_STRING_OKAY - # is will be dropped in a future patch, once we are sure the - # minimum supported libvirtd server we require is ok with that. - # Quoting libvirt.h: - # """Older servers lacked the ability to handle string typed - # parameters.[...] This flag is automatically set when needed, - # [...] however, manually setting the flag can be used to - # reject servers that cannot return typed strings [...]""" - - diskSamples = {} - for vmDrive in self._vm.getDiskDevices(): - diskSamples[vmDrive.name] = self._vm._dom.blockStatsFlags( - vmDrive.name, flags=libvirt.VIR_TYPED_PARAM_STRING_OKAY) - - return diskSamples - - def _sampleNet(self): - """ - Network interface statistics. Return value is a dict with a key - per network interface. Each value is a tuple of eight (8) elements. - - The meaning of each item in the value tuple is, in order: - * bytes received - * packets received - * number of errors reported receiving data - * number of incoming packets dropped - * bytes transmitted - * packets transmitted - * number of errors reported transmitting data - * number of outgoing packets dropped - - Example: - { - 'vnet0': (29562785L, 19999L, 0L, 0L, 803385L, 11673L, 0L, 0L) - } - """ - netSamples = {} - for nic in self._vm.getNicDevices(): - netSamples[nic.name] = self._vm._dom.interfaceStats(nic.name) - return netSamples - - def _sampleVcpuPinning(self): - """ - Virtual CPU pinning information. Return value is a list of - tuples, one per virtual CPU. - - The meaning of each item in the virtual CPU tuple is: - * virtual CPU number - * virtual CPU state - * CPU time used, in nanoseconds - * real CPU number, or -1 if offline - - virtual CPU state could be - 0: offline - 1: running - 2: blocked on resource - - Example: - [(0, 1, 26040000000L, 4), (1, 1, 12620000000L, 4)] - """ - vCpuInfos = self._vm._dom.vcpus() - return vCpuInfos[0] - - def _sampleBalloon(self): - """ - memory usage information. Return value is the memory in KBytes - used by the VM. - - Example: - 8388608L - """ - infos = self._vm._dom.info() - return infos[2] - - def _sampleCpuTune(self): - """ - virtual cpu tuning information. Return value is a dict - with at least six key/value pairs, defined as follows: - * vcpu_quota: max allowed bandwith, in microseconds. - -1 means 'infinite' - * vcpu_period: timeframe on which the virtual cpu quota is - enforced, in microseconds. - * emulator_quota: max allowd bandwith for emulator threads, - in microseconds. -1 means 'infinite'. - * emulator_period: timeframe on which the emulator quota is - enforced, in microseconds. - * cpu_shares: weight of this VM. This value is meaningful - only if compared with the other values of - the running vms. - * vcpuCount: number of virtual CPUs used by the VM - - another key may be optionally present: - * vcpuLimit: FIXME add docs - Extra keys will be ignored. - - Example: - { - 'vcpu_quota': -1L, - 'vcpu_period': 1000L, - 'emulator_period': 100000L, - 'emulator_quota': -1L, - 'cpu_shares': 1020L - 'vcpuCount': 2 - } - """ - infos = self._vm._dom.schedulerParameters() - infos['vcpuCount'] = self._vm._dom.vcpusFlags( - libvirt.VIR_DOMAIN_VCPU_CURRENT) - - metadataCpuLimit = None - - try: - if VmStatsThread._libvirt_metadata_supported: - metadataCpuLimit = self._vm._dom.metadata( - libvirt.VIR_DOMAIN_METADATA_ELEMENT, - METADATA_VM_TUNE_URI, 0) - except libvirt.libvirtError as e: - if e.get_error_code() == libvirt.VIR_ERR_ARGUMENT_UNSUPPORTED: - VmStatsThread._libvirt_metadata_supported = False - self._log.error("libvirt does not support metadata") - - elif (e.get_error_code() - not in (libvirt.VIR_ERR_NO_DOMAIN, - libvirt.VIR_ERR_NO_DOMAIN_METADATA)): - # Non-existing VM and no metadata block are expected - # conditions and no reasons for concern here. - # All other errors should be reported. - self._log.warn("Failed to retrieve QoS metadata because of %s", - e) - - if metadataCpuLimit: - metadataCpuLimitXML = _domParseStr(metadataCpuLimit) - nodeList = \ - metadataCpuLimitXML.getElementsByTagName('vcpuLimit') - infos['vcpuLimit'] = nodeList[0].childNodes[0].data - - return infos - - def _getIoTuneStats(self, stats): - """ - Collect the current ioTune settings for all disks VDSM knows about. - - This assumes VDSM always has the correct info and nobody else is - touching the device without telling VDSM about it. - - TODO: We might want to move to XML parsing (first update) and events - once libvirt supports them: - https://bugzilla.redhat.com/show_bug.cgi?id=1114492 - """ - ioTuneInfo = [] - - for disk in self._vm.getDiskDevices(): - if "ioTune" in disk.specParams: - ioTuneInfo.append({ - "name": disk.name, - "path": disk.path, - "ioTune": disk.specParams["ioTune"] - }) - - stats['ioTune'] = ioTuneInfo - - def _diff(self, prev, curr, val): - return prev[val] - curr[val] - - def _usagePercentage(self, val, sampleInterval): - return 100 * val / sampleInterval / 1000 ** 3 - - def _getCpuStats(self, stats): - stats['cpuUser'] = 0.0 - stats['cpuSys'] = 0.0 - - sInfo, eInfo, sampleInterval = self.sampleCpu.getStats() - - if sInfo is None: - return - - try: - stats['cpuSys'] = self._usagePercentage( - self._diff(eInfo, sInfo, 'user_time') + - self._diff(eInfo, sInfo, 'system_time'), - sampleInterval) - stats['cpuUser'] = self._usagePercentage( - self._diff(eInfo, sInfo, 'cpu_time') - - self._diff(eInfo, sInfo, 'user_time') - - self._diff(eInfo, sInfo, 'system_time'), - sampleInterval) - - except (TypeError, ZeroDivisionError) as e: - self._log.exception("CPU stats not available: %s", e) - - def _getBalloonStats(self, stats): - max_mem = int(self._vm.conf.get('memSize')) * 1024 - - sample = self.sampleBalloon.getLastSample() - - for dev in self._vm.getBalloonDevicesConf(): - if dev['specParams']['model'] != 'none': - balloon_target = dev.get('target', max_mem) - break - else: - balloon_target = None - - stats['balloonInfo'] = {} - - # Do not return any balloon status info before we get all data - # MOM will ignore VMs with missing balloon information instead - # using incomplete data and computing wrong balloon targets - if balloon_target is not None and sample is not None: - stats['balloonInfo'].update({ - 'balloon_max': str(max_mem), - 'balloon_min': str( - int(self._vm.conf.get('memGuaranteedSize', '0')) * 1024), - 'balloon_cur': str(sample), - 'balloon_target': str(balloon_target) - }) - - def _getCpuTuneInfo(self, stats): - - sample = self.sampleCpuTune.getLastSample() - - # Handling the case when not enough samples exist - if sample is None: - return - - # Handling the case where quota is not set, setting to 0. - # According to libvirt API:"A quota with value 0 means no value." - # The value does not have to be present in some transient cases - if sample.get('vcpu_quota', _NO_CPU_QUOTA) != _NO_CPU_QUOTA: - stats['vcpuQuota'] = str(sample['vcpu_quota']) - - # Handling the case where period is not set, setting to 0. - # According to libvirt API:"A period with value 0 means no value." - # The value does not have to be present in some transient cases - if sample.get('vcpu_period', _NO_CPU_PERIOD) != _NO_CPU_PERIOD: - stats['vcpuPeriod'] = sample['vcpu_period'] - - def _getCpuCount(self, stats): - sample = self.sampleCpuTune.getLastSample() - - # Handling the case when not enough samples exist - if sample is None: - return - - if 'vcpuCount' in sample: - vcpuCount = sample['vcpuCount'] - if vcpuCount != -1: - stats['vcpuCount'] = vcpuCount - else: - self._log.error('Failed to get VM cpu count') - - def _getUserCpuTuneInfo(self, stats): - sample = self.sampleCpuTune.getLastSample() - - # Handling the case when not enough samples exist - if sample is None: - return - - if 'vcpuLimit' in sample: - value = sample['vcpuLimit'] - stats['vcpuUserLimit'] = value - - @classmethod - def _getNicStats(cls, name, model, mac, - start_sample, end_sample, interval): - ifSpeed = [100, 1000][model in ('e1000', 'virtio')] - - ifStats = {'macAddr': mac, - 'name': name, - 'speed': str(ifSpeed), - 'state': 'unknown'} - - ifStats['rxErrors'] = str(end_sample[2]) - ifStats['rxDropped'] = str(end_sample[3]) - ifStats['txErrors'] = str(end_sample[6]) - ifStats['txDropped'] = str(end_sample[7]) - - ifRxBytes = (100.0 * - ((end_sample[0] - start_sample[0]) % 2 ** 32) / - interval / ifSpeed / cls.MBPS_TO_BPS) - ifTxBytes = (100.0 * - ((end_sample[4] - start_sample[4]) % 2 ** 32) / - interval / ifSpeed / cls.MBPS_TO_BPS) - - ifStats['rxRate'] = '%.1f' % ifRxBytes - ifStats['txRate'] = '%.1f' % ifTxBytes - - ifStats['rx'] = str(end_sample[0]) - ifStats['tx'] = str(end_sample[4]) - ifStats['sampleTime'] = utils.monotonic_time() - - return ifStats - - def _getNetworkStats(self, stats): - stats['network'] = {} - sInfo, eInfo, sampleInterval = self.sampleNet.getStats() - - if sInfo is None: - return - - for nic in self._vm.getNicDevices(): - if nic.name.startswith('hostdev'): - continue - - # may happen if nic is a new hot-plugged one - if nic.name not in sInfo or nic.name not in eInfo: - continue - - stats['network'][nic.name] = self._getNicStats( - nic.name, nic.nicModel, nic.macAddr, - sInfo[nic.name], eInfo[nic.name], sampleInterval) - - def _getDiskStats(self, stats): - sInfo, eInfo, sampleInterval = self.sampleDisk.getStats() - - for vmDrive in self._vm.getDiskDevices(): - dStats = {} - try: - dStats = {'truesize': str(vmDrive.truesize), - 'apparentsize': str(vmDrive.apparentsize), - 'readLatency': '0', - 'writeLatency': '0', - 'flushLatency': '0'} - if isVdsmImage(vmDrive): - dStats['imageID'] = vmDrive.imageID - elif "GUID" in vmDrive: - dStats['lunGUID'] = vmDrive.GUID - if (sInfo and vmDrive.name in sInfo and - eInfo and vmDrive.name in eInfo): - # will be None if sampled during recovery - dStats.update(_calcDiskRate(vmDrive, sInfo, eInfo, - sampleInterval)) - dStats.update(_calcDiskLatency(vmDrive, sInfo, eInfo)) - - except (AttributeError, TypeError, ZeroDivisionError): - self._log.exception("Disk %s stats not available", - vmDrive.name) - - stats[vmDrive.name] = dStats - - def _getNumaStats(self, stats): - vmNumaNodeRuntimeMap = numaUtils.getVmNumaNodeRuntimeInfo(self._vm) - if vmNumaNodeRuntimeMap: - stats['vNodeRuntimeInfo'] = vmNumaNodeRuntimeMap - - def get(self): - stats = {} - - self._getCpuStats(stats) - self._getNetworkStats(stats) - self._getDiskStats(stats) - self._getBalloonStats(stats) - self._getNumaStats(stats) - self._getCpuTuneInfo(stats) - self._getCpuCount(stats) - self._getUserCpuTuneInfo(stats) - self._getIoTuneStats(stats) - - return stats - - def handleStatsException(self, ex): - # We currently handle only libvirt exceptions - if not hasattr(ex, "get_error_code"): - return False - - # We currently handle only the missing domain exception - if ex.get_error_code() != libvirt.VIR_ERR_NO_DOMAIN: - return False - - return True - - -def _calcDiskRate(vmDrive, sInfo, eInfo, sampleInterval): - return { - 'readRate': ( - (eInfo[vmDrive.name]['rd_bytes'] - - sInfo[vmDrive.name]['rd_bytes']) - / sampleInterval), - 'writeRate': ( - (eInfo[vmDrive.name]['wr_bytes'] - - sInfo[vmDrive.name]['wr_bytes']) - / sampleInterval)} - - -def _calcDiskLatency(vmDrive, sInfo, eInfo): - dname = vmDrive.name - - def compute_latency(ltype): - ops = ltype + '_operations' - operations = eInfo[dname][ops] - sInfo[dname][ops] - if not operations: - return 0 - times = ltype + '_total_times' - elapsed_time = eInfo[dname][times] - sInfo[dname][times] - return elapsed_time / operations - - return {'readLatency': str(compute_latency('rd')), - 'writeLatency': str(compute_latency('wr')), - 'flushLatency': str(compute_latency('flush'))} class TimeoutError(libvirt.libvirtError): -- To view, visit http://gerrit.ovirt.org/37597 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic62c3251b770c41b48ff6823f26bbba8d8801903 Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Francesco Romani <[email protected]> _______________________________________________ vdsm-patches mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches
