def estimate_qcow2_size(self, src_vol_params, dst_sd_id): """ Calculate volume allocation size for converting raw/qcow2 source volume to qcow2 volume on destination storage domain. Arguments: src_vol_params(dict): Dictionary returned from `storage.volume.Volume.getVolumeParams()` dst_sd_id(str) : Destination volume storage domain id Returns: Volume allocation in bytes """ # measure required size. qemu_measure = qemuimg.measure(image=src_vol_params['path'], format=sc.fmt2str( src_vol_params['volFormat']), output_format=qemuimg.FORMAT.QCOW2) # Adds extra room so we don't have to extend this disk immediately # when a vm is started. chunk_size_mb = config.getint("irs", "volume_utilization_chunk_mb") chunk_size = chunk_size_mb * MiB required = (qemu_measure["required"] + chunk_size) # Limit estimates size by maximum size. vol_class = sdCache.produce(dst_sd_id).getVolumeClass() max_size = vol_class.max_size(src_vol_params['capacity'], sc.COW_FORMAT) allocation = min(required, max_size) # Return estimated size of allocation. self.log.debug("Estimated allocation for qcow2 volume:" "%d", allocation) return allocation
def _extend_base_allocation(base_vol, top_vol): if not (base_vol.is_block() and base_vol.getFormat() == sc.COW_FORMAT): return # Measure the subchain from top to base. This gives us the required # allocation for merging top into base. log.debug("Measuring sub chain top=%r base=%r", top_vol.volUUID, base_vol.volUUID) measure = qemuimg.measure(top_vol.getVolumePath(), format=qemuimg.FORMAT.QCOW2, output_format=qemuimg.FORMAT.QCOW2, is_block=True, base=base_vol.getVolumePath()) log.debug("Measure result: %s", measure) # When merging we always copy the bitmaps from the top to base. Measure # gives us the size of the bitmaps in top *and* base, so this may allocate # more than needed, but bitmaps are small so it should be good enough. required_size = measure["required"] + measure.get("bitmaps", 0) # If the top volume is leaf, the base volume will become leaf after the # merge, so it needs more space. optimal_size = base_vol.optimal_cow_size(required_size, base_vol.getCapacity(), top_vol.isLeaf()) # Extend the volume. dom = sdCache.produce(base_vol.sdUUID) dom.extendVolume(base_vol.volUUID, optimal_size // MiB)
def check_measure(self, filename, compat, format, compressed): if format != qemuimg.FORMAT.RAW: filename = convert_to_qcow2(filename, compressed=compressed, compat=compat) qemu_info = qemuimg.info(filename) virtual_size = qemu_info["virtualsize"] qemu_measure = qemuimg.measure( filename, format=format, output_format=qemuimg.FORMAT.QCOW2) estimated_size = qemu_measure["required"] actual_size = converted_size(filename, compat=compat) error_pct = 100 * float(estimated_size - actual_size) / virtual_size assert estimated_size >= actual_size assert error_pct <= 0.1, error_pct
def check_measure(self, filename, compat, format, compressed): if format != qemuimg.FORMAT.RAW: filename = convert_to_qcow2(filename, compressed=compressed, compat=compat) qemu_info = qemuimg.info(filename) virtual_size = qemu_info["virtualsize"] qemu_measure = qemuimg.measure( filename, format=format, output_format=qemuimg.FORMAT.QCOW2) estimated_size = qemu_measure["required"] actual_size = converted_size(filename, compat=compat) error_pct = 100 * float(estimated_size - actual_size) / virtual_size assert estimated_size >= actual_size assert error_pct <= 0.1, error_pct