def test_finalize(self, sd_type, chain_len, base_index, top_index): with self.make_env(sd_type=sd_type, chain_len=chain_len) as env: base_vol = env.chain[base_index] top_vol = env.chain[top_index] subchain_info = dict(sd_id=base_vol.sdUUID, img_id=base_vol.imgUUID, base_id=base_vol.volUUID, top_id=top_vol.volUUID, base_generation=0) subchain = merge.SubchainInfo(subchain_info, 0) merge.finalize(subchain) # If top has a child, the child must now be rebased on base. if top_vol is not env.chain[-1]: child_vol = env.chain[top_index + 1] info = qemuimg.info(child_vol.volumePath) backing_file = volume.getBackingVolumePath( subchain.img_id, subchain.base_id) assert info['backingfile'] == backing_file # verify syncVolumeChain arguments self.check_sync_volume_chain(subchain, env.chain[-1].volUUID) new_chain = [vol.volUUID for vol in env.chain] new_chain.remove(top_vol.volUUID) assert image.Image.syncVolumeChain.actual_chain == new_chain assert base_vol.getLegality() == sc.LEGAL_VOL
def _rebase_operation(base, child): backing = volume.getBackingVolumePath(base.imgUUID, base.volUUID) backing_format = sc.fmt2str(base.getFormat()) operation = qemuimg.rebase(image=child.volumePath, backing=backing, format=qemuimg.FORMAT.QCOW2, backingFormat=backing_format, unsafe=True) return operation
def _interImagesCopy(self, destDom, srcSdUUID, imgUUID, chains): srcLeafVol = chains['srcChain'][-1] dstLeafVol = chains['dstChain'][-1] try: # Prepare the whole chains before the copy srcLeafVol.prepare(rw=False) dstLeafVol.prepare(rw=True, chainrw=True, setrw=True) except Exception: self.log.error("Unexpected error", exc_info=True) # teardown volumes self.__cleanupMove(srcLeafVol, dstLeafVol) raise try: for srcVol in chains['srcChain']: # Do the actual copy try: dstVol = destDom.produceVolume(imgUUID=imgUUID, volUUID=srcVol.volUUID) if workarounds.invalid_vm_conf_disk(srcVol): srcFormat = dstFormat = qemuimg.FORMAT.RAW else: srcFormat = sc.fmt2str(srcVol.getFormat()) dstFormat = sc.fmt2str(dstVol.getFormat()) parentVol = dstVol.getParentVolume() if parentVol is not None: backing = volume.getBackingVolumePath( imgUUID, parentVol.volUUID) backingFormat = sc.fmt2str(parentVol.getFormat()) else: backing = None backingFormat = None if (destDom.supportsSparseness and dstVol.getType() == sc.PREALLOCATED_VOL): preallocation = qemuimg.PREALLOCATION.FALLOC else: preallocation = None operation = qemuimg.convert( srcVol.getVolumePath(), dstVol.getVolumePath(), srcFormat=srcFormat, dstFormat=dstFormat, dstQcow2Compat=destDom.qcow2_compat(), backing=backing, backingFormat=backingFormat, preallocation=preallocation, unordered_writes=destDom.recommends_unordered_writes( dstVol.getFormat()), create=not destDom.is_block(), ) with utils.stopwatch("Copy volume %s" % srcVol.volUUID): self._run_qemuimg_operation(operation) except ActionStopped: raise except se.StorageException: self.log.error("Unexpected error", exc_info=True) raise except Exception: self.log.error( "Copy image error: image=%s, src domain=%s," " dst domain=%s", imgUUID, srcSdUUID, destDom.sdUUID, exc_info=True) raise se.CopyImageError() finally: # teardown volumes self.__cleanupMove(srcLeafVol, dstLeafVol)
def backing_path(self): parent_vol = self.volume.getParentVolume() if not parent_vol: return None return volume.getBackingVolumePath(self.img_id, parent_vol.volUUID)
def _interImagesCopy(self, destDom, srcSdUUID, imgUUID, chains): srcLeafVol = chains['srcChain'][-1] dstLeafVol = chains['dstChain'][-1] try: # Prepare the whole chains before the copy srcLeafVol.prepare(rw=False) dstLeafVol.prepare(rw=True, chainrw=True, setrw=True) except Exception: self.log.error("Unexpected error", exc_info=True) # teardown volumes self.__cleanupMove(srcLeafVol, dstLeafVol) raise try: for srcVol in chains['srcChain']: # Do the actual copy try: dstVol = destDom.produceVolume(imgUUID=imgUUID, volUUID=srcVol.volUUID) if workarounds.invalid_vm_conf_disk(srcVol): srcFormat = dstFormat = qemuimg.FORMAT.RAW else: srcFormat = sc.fmt2str(srcVol.getFormat()) dstFormat = sc.fmt2str(dstVol.getFormat()) parentVol = dstVol.getParentVolume() if parentVol is not None: backing = volume.getBackingVolumePath( imgUUID, parentVol.volUUID) backingFormat = sc.fmt2str(parentVol.getFormat()) else: backing = None backingFormat = None operation = qemuimg.convert( srcVol.getVolumePath(), dstVol.getVolumePath(), srcFormat=srcFormat, dstFormat=dstFormat, dstQcow2Compat=destDom.qcow2_compat(), backing=backing, backingFormat=backingFormat, unordered_writes=destDom.recommends_unordered_writes( dstVol.getFormat()), create=dstVol.requires_create(), target_is_zero=dstVol.zero_initialized(), ) with utils.stopwatch("Copy volume {}".format( srcVol.volUUID), level=logging.INFO, log=self.log): self._run_qemuimg_operation(operation) except ActionStopped: raise except se.StorageException: self.log.error("Unexpected error", exc_info=True) raise except Exception: self.log.error( "Copy image error: image=%s, src domain=%s," " dst domain=%s", imgUUID, srcSdUUID, destDom.sdUUID, exc_info=True) raise se.CopyImageError() finally: # teardown volumes self.__cleanupMove(srcLeafVol, dstLeafVol)