def disks(vm, stats, first_sample, last_sample, interval): if first_sample is None or last_sample is None: return None # libvirt does not guarantee that disk will returned in the same # order across calls. It is usually like this, but not always, # for example if hotplug/hotunplug comes into play. # To be safe, we need to find the mapping after each call. first_indexes = _find_bulk_stats_reverse_map(first_sample, 'block') last_indexes = _find_bulk_stats_reverse_map(last_sample, 'block') disk_stats = {} for vm_drive in vm.getDiskDevices(): drive_stats = {} try: drive_stats = { 'truesize': str(vm_drive.truesize), 'apparentsize': str(vm_drive.apparentsize), 'readLatency': '0', 'writeLatency': '0', 'flushLatency': '0' } if isVdsmImage(vm_drive): drive_stats['imageID'] = vm_drive.imageID elif "GUID" in vm_drive: drive_stats['lunGUID'] = vm_drive.GUID if (vm_drive.name in first_indexes and vm_drive.name in last_indexes): # will be None if sampled during recovery if interval <= 0: logging.warning( 'invalid interval %i when calculating ' 'stats for vm %s disk %s', interval, vm.id, vm_drive.name) else: drive_stats.update( _disk_rate( first_sample, first_indexes[vm_drive.name], last_sample, last_indexes[vm_drive.name], interval)) drive_stats.update( _disk_latency( first_sample, first_indexes[vm_drive.name], last_sample, last_indexes[vm_drive.name])) drive_stats.update( _disk_iops_bytes( first_sample, first_indexes[vm_drive.name], last_sample, last_indexes[vm_drive.name])) except AttributeError: logging.exception("Disk %s stats not available", vm_drive.name) disk_stats[vm_drive.name] = drive_stats if disk_stats: stats['disks'] = disk_stats return stats
def _collect(self, vm): data = vm.status() data['startTime'] = vm.start_time if vm.lastStatus != vmstatus.DOWN: guestInfo = vm.guestAgent.getGuestInfo() data['username'] = guestInfo['username'] data['guestIPs'] = guestInfo['guestIPs'] data['guestFQDN'] = guestInfo['guestFQDN'] else: data['username'] = "" data['guestIPs'] = "" data['guestFQDN'] = "" if 'sysprepInf' in data: del data['sysprepInf'] if 'floppy' in data: del data['floppy'] for drive in data.get('drives', []): for d in vm.getDiskDevices(): if isVdsmImage(d) and drive.get('volumeID') == d.volumeID: drive['truesize'] = str(d.truesize) drive['apparentsize'] = str(d.apparentsize) data['_blockJobs'] = utils.picklecopy(vm.conf.get('_blockJobs', {})) return data
def _collect(self, vm): data = vm.status() data['startTime'] = vm.start_time if vm.lastStatus != vmstatus.DOWN: guestInfo = vm.guestAgent.getGuestInfo() data['username'] = guestInfo['username'] data['guestIPs'] = guestInfo['guestIPs'] data['guestFQDN'] = guestInfo['guestFQDN'] else: data['username'] = "" data['guestIPs'] = "" data['guestFQDN'] = "" if 'sysprepInf' in data: del data['sysprepInf'] if 'floppy' in data: del data['floppy'] for drive in data.get('drives', []): for d in vm.getDiskDevices(): if isVdsmImage(d) and drive.get('volumeID') == d.volumeID: drive['truesize'] = str(d.truesize) drive['apparentsize'] = str(d.apparentsize) data['_blockJobs'] = utils.picklecopy( vm.conf.get('_blockJobs', {})) return data
def teardownVolumePath(self, drive): res = {'status': doneCode} try: if isVdsmImage(drive): res = self.irs.teardownImage(drive['domainID'], drive['poolID'], drive['imageID']) except TypeError: # paths (strings) are not deactivated if not isinstance(drive, basestring): self.log.warning("Drive is not a vdsm image: %s", drive, exc_info=True) return res['status']['code']
def disk_info(vm_drive): drive_stats = { 'truesize': str(vm_drive.truesize), 'apparentsize': str(vm_drive.apparentsize), 'readLatency': '0', 'writeLatency': '0', 'flushLatency': '0' } if isVdsmImage(vm_drive): drive_stats['imageID'] = vm_drive.imageID elif "GUID" in vm_drive: drive_stats['lunGUID'] = vm_drive.GUID return drive_stats
def disk_info(vm_drive): drive_stats = { 'truesize': str(vm_drive.truesize), 'apparentsize': str(vm_drive.apparentsize), 'readLatency': '0', 'writeLatency': '0', 'flushLatency': '0', 'writtenBytes': '0', 'writeOps': '0', 'readOps': '0', 'readBytes': '0', 'readRate': '0.0', 'writeRate': '0.0', } if isVdsmImage(vm_drive): drive_stats['imageID'] = vm_drive.imageID elif "GUID" in vm_drive: drive_stats['lunGUID'] = vm_drive.GUID return drive_stats
def prepareVolumePath(self, drive, vmId=None): if type(drive) is dict: device = drive['device'] # PDIV drive format if device == 'disk' and isVdsmImage(drive): res = self.irs.prepareImage( drive['domainID'], drive['poolID'], drive['imageID'], drive['volumeID']) if res['status']['code']: raise vm.VolumeError(drive) volPath = res['path'] # The order of imgVolumesInfo is not guaranteed drive['volumeChain'] = res['imgVolumesInfo'] drive['volumeInfo'] = res['info'] # GUID drive format elif "GUID" in drive: res = self.irs.getDevicesVisibility([drive["GUID"]]) if not res["visible"][drive["GUID"]]: raise vm.VolumeError(drive) res = self.irs.appropriateDevice(drive["GUID"], vmId) if res['status']['code']: raise vm.VolumeError(drive) # Update size for LUN volume drive["truesize"] = res['truesize'] drive["apparentsize"] = res['apparentsize'] volPath = res['path'] # cdrom and floppy drives elif (device in ('cdrom', 'floppy') and 'specParams' in drive): params = drive['specParams'] if 'vmPayload' in params: volPath = self._prepareVolumePathFromPayload( vmId, device, params['vmPayload']) # next line can be removed in future, when < 3.3 engine # is not supported elif (params.get('path', '') == '' and drive.get('path', '') == ''): volPath = '' else: volPath = drive.get('path', '') elif "path" in drive: volPath = drive['path'] else: raise vm.VolumeError(drive) # For BC sake: None as argument elif not drive: volPath = drive # For BC sake: path as a string. elif os.path.exists(drive): volPath = drive else: raise vm.VolumeError(drive) self.log.info("prepared volume path: %s", volPath) return volPath
def prepareVolumePath(self, drive, vmId=None): if type(drive) is dict: device = drive['device'] # PDIV drive format # Since version 4.2 cdrom may use a PDIV format if device in ("cdrom", "disk") and isVdsmImage(drive): res = self.irs.prepareImage(drive['domainID'], drive['poolID'], drive['imageID'], drive['volumeID']) if res['status']['code']: raise vm.VolumeError(drive) # The order of imgVolumesInfo is not guaranteed drive['volumeChain'] = res['imgVolumesInfo'] drive['volumeInfo'] = res['info'] if drive.get('diskType') == DISK_TYPE.NETWORK: if device == "cdrom": raise exception.UnsupportedOperation( "A cdrom device is not supported as network disk", drive=drive) # Not applicable for Ceph network disk as # Ceph disks are not vdsm images volPath = self._prepare_network_drive(drive, res) else: if 'diskType' not in drive: if res['info']['type'] == DISK_TYPE.BLOCK: drive['diskType'] = DISK_TYPE.BLOCK else: # Volume type may be 'network', but if engine did # not speicfy the type, we must use 'file'. drive['diskType'] = DISK_TYPE.FILE volPath = res['path'] # GUID drive format elif "GUID" in drive: res = self.irs.getDevicesVisibility([drive["GUID"]]) if not res["visible"][drive["GUID"]]: raise vm.VolumeError("Drive %r not visible" % drive["GUID"]) res = self.irs.appropriateDevice(drive["GUID"], vmId, 'mpath') if res['status']['code']: raise vm.VolumeError("Cannot appropriate drive %r" % drive["GUID"]) # Update size for LUN volume drive["truesize"] = res['truesize'] drive["apparentsize"] = res['apparentsize'] if 'diskType' not in drive: drive['diskType'] = DISK_TYPE.BLOCK volPath = res['path'] elif "RBD" in drive: res = self.irs.appropriateDevice(drive["RBD"], vmId, 'rbd') volPath = res['path'] # cdrom and floppy drives elif (device in ('cdrom', 'floppy') and 'specParams' in drive): params = drive['specParams'] if 'vmPayload' in params: volPath = self._prepareVolumePathFromPayload( vmId, device, params['vmPayload']) # next line can be removed in future, when < 3.3 engine # is not supported elif (params.get('path', '') == '' and drive.get('path', '') == ''): volPath = '' else: volPath = drive.get('path', '') elif "path" in drive: volPath = drive['path'] else: raise vm.VolumeError(drive) # Noramalize the missing diskType when cluster version < 4.2. if 'diskType' not in drive: drive['diskType'] = DISK_TYPE.FILE # For BC sake: None as argument elif not drive: volPath = drive # For BC sake: path as a string. elif os.path.exists(drive): volPath = drive else: raise vm.VolumeError(drive) self.log.info("prepared volume path: %s", volPath) return volPath
def prepareVolumePath(self, drive, vmId=None): if type(drive) is dict: device = drive['device'] # PDIV drive format if device == 'disk' and isVdsmImage(drive): res = self.irs.prepareImage(drive['domainID'], drive['poolID'], drive['imageID'], drive['volumeID']) if res['status']['code']: raise vm.VolumeError(drive) # The order of imgVolumesInfo is not guaranteed drive['volumeChain'] = res['imgVolumesInfo'] drive['volumeInfo'] = res['info'] # Not applicable for Ceph network disk as # Ceph disks are not vdsm images if drive.get('diskType') == DISK_TYPE.NETWORK: volPath = self._prepare_network_drive(drive, res) else: volPath = res['path'] # GUID drive format elif "GUID" in drive: res = self.irs.getDevicesVisibility([drive["GUID"]]) if not res["visible"][drive["GUID"]]: raise vm.VolumeError(drive) res = self.irs.appropriateDevice(drive["GUID"], vmId) if res['status']['code']: raise vm.VolumeError(drive) # Update size for LUN volume drive["truesize"] = res['truesize'] drive["apparentsize"] = res['apparentsize'] volPath = res['path'] # cdrom and floppy drives elif (device in ('cdrom', 'floppy') and 'specParams' in drive): params = drive['specParams'] if 'vmPayload' in params: volPath = self._prepareVolumePathFromPayload( vmId, device, params['vmPayload']) # next line can be removed in future, when < 3.3 engine # is not supported elif (params.get('path', '') == '' and drive.get('path', '') == ''): volPath = '' else: volPath = drive.get('path', '') elif "path" in drive: volPath = drive['path'] else: raise vm.VolumeError(drive) # For BC sake: None as argument elif not drive: volPath = drive # For BC sake: path as a string. elif os.path.exists(drive): volPath = drive else: raise vm.VolumeError(drive) self.log.info("prepared volume path: %s", volPath) return volPath
def test_is_vdsm_image(pdiv, expected): assert expected == utils.isVdsmImage(pdiv)
def prepareVolumePath(self, drive, vmId=None): if type(drive) is dict: device = drive['device'] # PDIV drive format # Since version 4.2 cdrom may use a PDIV format if device in ("cdrom", "disk") and isVdsmImage(drive): res = self.irs.prepareImage( drive['domainID'], drive['poolID'], drive['imageID'], drive['volumeID']) if res['status']['code']: raise vm.VolumeError(drive) # The order of imgVolumesInfo is not guaranteed drive['volumeChain'] = res['imgVolumesInfo'] drive['volumeInfo'] = res['info'] if drive.get('diskType') == DISK_TYPE.NETWORK: if device == "cdrom": raise exception.UnsupportedOperation( "A cdrom device is not supported as network disk", drive=drive) # Not applicable for Ceph network disk as # Ceph disks are not vdsm images volPath = self._prepare_network_drive(drive, res) else: if 'diskType' not in drive: if res['info']['type'] == DISK_TYPE.BLOCK: drive['diskType'] = DISK_TYPE.BLOCK else: # Volume type may be 'network', but if engine did # not speicfy the type, we must use 'file'. drive['diskType'] = DISK_TYPE.FILE volPath = res['path'] # GUID drive format elif "GUID" in drive: res = self.irs.getDevicesVisibility([drive["GUID"]]) if not res["visible"][drive["GUID"]]: raise vm.VolumeError( "Drive %r not visible" % drive["GUID"]) res = self.irs.appropriateDevice(drive["GUID"], vmId, 'mpath') if res['status']['code']: raise vm.VolumeError( "Cannot appropriate drive %r" % drive["GUID"]) # Update size for LUN volume drive["truesize"] = res['truesize'] drive["apparentsize"] = res['apparentsize'] if 'diskType' not in drive: drive['diskType'] = DISK_TYPE.BLOCK volPath = res['path'] elif "RBD" in drive: res = self.irs.appropriateDevice(drive["RBD"], vmId, 'rbd') volPath = res['path'] # cdrom and floppy drives elif (device in ('cdrom', 'floppy') and 'specParams' in drive): params = drive['specParams'] if 'vmPayload' in params: volPath = self._prepareVolumePathFromPayload( vmId, device, params['vmPayload']) # next line can be removed in future, when < 3.3 engine # is not supported elif (params.get('path', '') == '' and drive.get('path', '') == ''): volPath = '' else: volPath = drive.get('path', '') elif "path" in drive: volPath = drive['path'] else: raise vm.VolumeError(drive) # Noramalize the missing diskType when cluster version < 4.2. if 'diskType' not in drive: drive['diskType'] = DISK_TYPE.FILE # For BC sake: None as argument elif not drive: volPath = drive # For BC sake: path as a string. elif os.path.exists(drive): volPath = drive else: raise vm.VolumeError(drive) self.log.info("prepared volume path: %s", volPath) return volPath