private void syncDbRecordsMergeFailure() { DiskImage curr = getDestinationDiskImage(); while (!curr.getImageId().equals(getDiskImage().getImageId())) { curr = getDbFacade().getDiskImageDao().getSnapshotById(curr.getParentId()); getImageDao().updateStatus(curr.getImageId(), ImageStatus.ILLEGAL); } }
@Override public String getVolumeStringRepresentation() { return MemoryUtils.createMemoryStateString( storageDomainId, storagePool.getId(), memoryDisk.getId(), memoryDisk.getImageId(), metadataDisk.getId(), metadataDisk.getImageId()); }
public static void fillImagesBySnapshots(VM vm) { for (Disk disk : vm.getDiskMap().values()) { if (disk.getDiskStorageType().isInternal()) { DiskImage diskImage = (DiskImage) disk; diskImage.getSnapshots().addAll(getAllImageSnapshots(diskImage.getImageId())); } } }
// function return the index of image that is its child private static int getNextImage(List<DiskImage> images, DiskImage curr) { for (int i = 0; i < images.size(); i++) { if (images.get(i).getParentId().equals(curr.getImageId())) { return i; } } return -1; }
/** * Returns a list of image IDs for the specified DiskImages collection. * * @param diskImages collection of DiskImages * @return list of image IDs ordered by the order of the retrieved list. */ public static List<Guid> getDiskImageIds(List<DiskImage> diskImages) { List<Guid> result = new ArrayList<>(); if (diskImages != null) { for (DiskImage diskImage : diskImages) { result.add(diskImage.getImageId()); } } return result; }
/** * Gets a map of DiskImage IDs to DiskImage objects * * @param diskImages collection of DiskImage objects to create the map for * @return map object is the collection is not null */ public static Map<Guid, DiskImage> getDiskImagesByIdMap(Collection<DiskImage> diskImages) { Map<Guid, DiskImage> result = new HashMap<>(); if (diskImages != null) { for (DiskImage diskImage : diskImages) { result.put(diskImage.getImageId(), diskImage); } } return result; }
/** * Adds a disk image (Adds image, disk, and relevant entities , but not VmDevice) This may be * useful for Clone VMs, where besides adding images it is required to copy all vm devices * (VmDeviceUtils.copyVmDevices) from the source VM. */ public static void addDiskImageWithNoVmDevice(DiskImage image) { addDiskImageWithNoVmDevice( image, image.getActive(), new ImageStorageDomainMap( image.getImageId(), image.getStorageIds().get(0), image.getQuotaId(), image.getDiskProfileId())); }
private void updateDiskVmSnapshotId() { Guid snapshotId = getSnapshotDao().getId(getVmId(), SnapshotType.ACTIVE); if (disk.getDiskStorageType().isInternal()) { DiskImage diskImage = ((DiskImage) disk); getImageDao().updateImageVmSnapshotId(diskImage.getImageId(), snapshotId); } else { throw new EngineException( EngineError.StorageException, "update of snapshot id was initiated for unsupported disk type"); } }
/** * Adds a disk image (Adds image with active flag according to the value in image, using the first * storage domain in the storage id as entry to the storage domain map) * * @param image DiskImage to add */ public static void addDiskImage(DiskImage image, Guid vmId) { addDiskImage( image, image.getActive(), new ImageStorageDomainMap( image.getImageId(), image.getStorageIds().get(0), image.getQuotaId(), image.getDiskProfileId()), vmId); }
/** * Add image and related entities to DB (Adds image, disk image dynamic and image storage domain * map) * * @param image the image to add * @param active if true the image will be active * @param imageStorageDomainMap entry of mapping between the storage domain and the image */ public static void addImage( DiskImage image, boolean active, ImageStorageDomainMap imageStorageDomainMap) { image.setActive(active); DbFacade.getInstance().getImageDao().save(image.getImage()); DiskImageDynamic diskDynamic = new DiskImageDynamic(); diskDynamic.setId(image.getImageId()); diskDynamic.setActualSize(image.getActualSizeInBytes()); DbFacade.getInstance().getDiskImageDynamicDao().save(diskDynamic); if (imageStorageDomainMap != null) { DbFacade.getInstance().getImageStorageDomainMapDao().save(imageStorageDomainMap); } }
/** * Prepare a single {@link org.ovirt.engine.core.common.businessentities.Snapshot} object * representing a snapshot of a given VM without the given disk, substituting a new disk in its * place if a new disk is provided to the method. */ public static Snapshot prepareSnapshotConfigWithAlternateImage( Snapshot snapshot, Guid oldImageId, DiskImage newImage) { try { OvfManager ovfManager = new OvfManager(); String snapConfig = snapshot.getVmConfiguration(); if (snapshot.isVmConfigurationAvailable() && snapConfig != null) { VM vmSnapshot = new VM(); ArrayList<DiskImage> snapshotImages = new ArrayList<>(); ovfManager.importVm(snapConfig, vmSnapshot, snapshotImages, new ArrayList<>()); // Remove the image from the disk list Iterator<DiskImage> diskIter = snapshotImages.iterator(); while (diskIter.hasNext()) { DiskImage imageInList = diskIter.next(); if (imageInList.getImageId().equals(oldImageId)) { log.debug( "Recreating vmSnapshot '{}' without the image '{}'", snapshot.getId(), oldImageId); diskIter.remove(); break; } } if (newImage != null) { log.debug( "Adding image '{}' to vmSnapshot '{}'", newImage.getImageId(), snapshot.getId()); snapshotImages.add(newImage); } String newOvf = ovfManager.exportVm( vmSnapshot, snapshotImages, ClusterUtils.getCompatibilityVersion(vmSnapshot)); snapshot.setVmConfiguration(newOvf); } } catch (OvfReaderException e) { log.error("Can't remove image '{}' from snapshot '{}'", oldImageId, snapshot.getId()); } return snapshot; }
public static DiskImage cloneDiskImage( Guid storageDomainId, Guid newImageGroupId, Guid newImageGuid, DiskImage srcDiskImage, Guid diskProfileId, Guid snapshotId, DiskImage diskImageFromClient) { DiskImage clonedDiskImage = DiskImage.copyOf(srcDiskImage); clonedDiskImage.setImageId(newImageGuid); clonedDiskImage.setParentId(Guid.Empty); clonedDiskImage.setImageTemplateId(Guid.Empty); clonedDiskImage.setVmSnapshotId(snapshotId); clonedDiskImage.setId(newImageGroupId); clonedDiskImage.setLastModifiedDate(new Date()); clonedDiskImage.setvolumeFormat(srcDiskImage.getVolumeFormat()); clonedDiskImage.setVolumeType(srcDiskImage.getVolumeType()); ArrayList<Guid> storageIds = new ArrayList<>(); storageIds.add(storageDomainId); clonedDiskImage.setStorageIds(storageIds); clonedDiskImage.setDiskProfileId(diskProfileId); // If volume information was changed at client , use its volume information. // If volume information was not changed at client - use the volume information of the ancestral // image if (diskImageFromClient != null) { if (volumeInfoChanged(diskImageFromClient, srcDiskImage)) { changeVolumeInfo(clonedDiskImage, diskImageFromClient); } else { DiskImage ancestorDiskImage = getDiskImageDao().getAncestor(srcDiskImage.getImageId()); changeVolumeInfo(clonedDiskImage, ancestorDiskImage); } } else { DiskImage ancestorDiskImage = getDiskImageDao().getAncestor(srcDiskImage.getImageId()); changeVolumeInfo(clonedDiskImage, ancestorDiskImage); } return clonedDiskImage; }
private VmTemplate createVmTemplate() { if (vmTemplate == null) { vmTemplate = new VmTemplate(); vmTemplate.setStoragePoolId(STORAGE_POOL_ID); DiskImage image = createDiskImageTemplate(); vmTemplate.getDiskTemplateMap().put(image.getImageId(), image); HashMap<Guid, DiskImage> diskImageMap = new HashMap<>(); DiskImage diskImage = createDiskImage(REQUIRED_DISK_SIZE_GB); diskImageMap.put(diskImage.getId(), diskImage); vmTemplate.setDiskImageMap(diskImageMap); } return vmTemplate; }
private boolean removeVm() { final List<DiskImage> diskImages = DisksFilter.filterImageDisks(getVm().getDiskList(), ONLY_NOT_SHAREABLE, ONLY_ACTIVE); final List<LunDisk> lunDisks = DisksFilter.filterLunDisks(getVm().getDiskMap().values(), ONLY_NOT_SHAREABLE); for (VmNic nic : getInterfaces()) { new ExternalNetworkManager(nic).deallocateIfExternal(); } removeMemoryVolumes(); TransactionSupport.executeInNewTransaction( () -> { removeVmFromDb(); if (getParameters().isRemoveDisks()) { for (DiskImage image : diskImages) { getCompensationContext().snapshotEntityStatus(image.getImage(), ImageStatus.ILLEGAL); ImagesHandler.updateImageStatus(image.getImage().getId(), ImageStatus.LOCKED); } for (LunDisk lunDisk : lunDisks) { ImagesHandler.removeLunDisk(lunDisk); } getCompensationContext().stateChanged(); } else { for (DiskImage image : diskImages) { imageDao.updateImageVmSnapshotId(image.getImageId(), null); } } return null; }); Collection<DiskImage> unremovedDisks = Collections.emptyList(); if (getParameters().isRemoveDisks()) { if (!diskImages.isEmpty()) { unremovedDisks = removeVmImages(diskImages).getActionReturnValue(); } unremovedDisks.addAll(removeCinderDisks()); if (!unremovedDisks.isEmpty()) { processUnremovedDisks(unremovedDisks); return false; } } vmDeleted.fire(getVmId()); return true; }
private ImagesContainterParametersBase buildRemoveSnapshotSingleDiskParameters() { ImagesContainterParametersBase parameters = new ImagesContainterParametersBase(imageId, vmId); DiskImage dest = DbFacade.getInstance().getDiskImageDao().getAllSnapshotsForParent(imageId).get(0); parameters.setDestinationImageId(dest.getImageId()); parameters.setEntityInfo(enclosingCommand.getParameters().getEntityInfo()); parameters.setParentParameters(enclosingCommand.getParameters()); parameters.setParentCommand(enclosingCommand.getActionType()); parameters.setWipeAfterDelete(dest.isWipeAfterDelete()); parameters.setSessionId(enclosingCommand.getParameters().getSessionId()); return parameters; }
private void setUpDaoMocks() { // Disk Image Dao List<Disk> returnArray = new ArrayList<>(); returnArray.add(pluggedDisk); returnArray.add(unpluggedDisk); returnArray.add(pluggedDiskSnapshot); returnArray.add(unpluggedDiskSnapshot); when(diskDaoMock.getAllForVm(vmID, getUser().getId(), getQueryParameters().isFiltered())) .thenReturn(returnArray); when(diskVmElementDao.get(any(VmDeviceId.class))) .thenReturn(new DiskVmElement(new VmDeviceId())); // Snapshots doReturn( new ArrayList<>( Collections.nCopies( NUM_DISKS_OF_EACH_KIND, createDiskSnapshot(pluggedDisk.getId())))) .when(diskImageDao) .getAllSnapshotsForLeaf(pluggedDisk.getImageId()); doReturn(Collections.nCopies(NUM_DISKS_OF_EACH_KIND, createDiskSnapshot(unpluggedDisk.getId()))) .when(diskImageDao) .getAllSnapshotsForLeaf(unpluggedDisk.getImageId()); doReturn( new ArrayList<>( Collections.nCopies( NUM_DISKS_OF_EACH_KIND, createDiskSnapshot(pluggedDiskSnapshot.getId())))) .when(diskImageDao) .getAllSnapshotsForLeaf(pluggedDiskSnapshot.getImageId()); doReturn( Collections.nCopies( NUM_DISKS_OF_EACH_KIND, createDiskSnapshot(unpluggedDiskSnapshot.getId()))) .when(diskImageDao) .getAllSnapshotsForLeaf(unpluggedDiskSnapshot.getImageId()); }
public static List<DiskImage> getSnapshotsDummiesForStorageAllocations( Collection<DiskImage> originalDisks) { List<DiskImage> diskDummies = new ArrayList<>(); for (DiskImage snapshot : originalDisks) { DiskImage clone = DiskImage.copyOf(snapshot); // Add the child snapshot into which the deleted snapshot is going to be merged to the // DiskImage for StorageDomainValidator to handle List<DiskImage> snapshots = DbFacade.getInstance().getDiskImageDao().getAllSnapshotsForParent(clone.getImageId()); clone.getSnapshots().clear(); clone .getSnapshots() .add(clone); // Add the clone itself since snapshots should contain the entire chain. clone.getSnapshots().addAll(snapshots); diskDummies.add(clone); } return diskDummies; }
private static DiskImage isImageExist(Guid storagePoolId, DiskImage image) { DiskImage fromIrs = null; try { Guid storageDomainId = image.getStorageIds().get(0); Guid imageGroupId = image.getId() != null ? image.getId() : Guid.Empty; fromIrs = (DiskImage) Backend.getInstance() .getResourceManager() .runVdsCommand( VDSCommandType.GetImageInfo, new GetImageInfoVDSCommandParameters( storagePoolId, storageDomainId, imageGroupId, image.getImageId())) .getReturnValue(); } catch (Exception e) { log.debug("Unable to get image info from from storage", e); } return fromIrs; }
@Mapping( from = org.ovirt.engine.core.common.businessentities.storage.Disk.class, to = DiskSnapshot.class) public static DiskSnapshot map( org.ovirt.engine.core.common.businessentities.storage.Disk entity, DiskSnapshot template) { if (template == null) { template = new DiskSnapshot(); } DiskSnapshot model = (DiskSnapshot) DiskMapper.map(entity, template); Disk disk = new Disk(); disk.setId(entity.getId().toString()); model.setDisk(disk); DiskImage diskImage = (DiskImage) entity; model.setId(diskImage.getImageId().toString()); model.setImageId(null); return model; }
public static DiskImage createDiskImageWithExcessData(DiskImage diskImage, Guid sdId) { DiskImage dummy = DiskImage.copyOf(diskImage); dummy.setStorageIds(new ArrayList<>(Collections.singletonList(sdId))); dummy.getSnapshots().addAll(getAllImageSnapshots(dummy.getImageId())); return dummy; }
/** * After merging the snapshots, update the image and snapshot records in the database to reflect * the changes. This handles either forward or backwards merge (detected). It will either then * remove the images, or mark them illegal (to handle the case where image deletion failed). * * @param removeImages Remove the images from the database, or if false, only mark them illegal */ private void syncDbRecords(boolean removeImages) { // If deletion failed after a backwards merge, the snapshots' images need to be swapped // as they would upon success. Instead of removing them, mark them illegal. DiskImage baseImage = getDiskImage(); DiskImage topImage = getDestinationDiskImage(); // The vdsm merge verb may decide to perform a forward or backward merge. if (topImage == null) { log.debug("No merge destination image, not updating image/snapshot association"); } else if (getParameters().getMergeStatusReturnValue().getBlockJobType() == VmBlockJobType.PULL) { // For forward merge, the volume format and type may change. topImage.setvolumeFormat(baseImage.getVolumeFormat()); topImage.setVolumeType(baseImage.getVolumeType()); topImage.setParentId(baseImage.getParentId()); topImage.setImageStatus(ImageStatus.OK); getBaseDiskDao().update(topImage); getImageDao().update(topImage.getImage()); updateDiskImageDynamic(topImage); updateVmConfigurationForImageRemoval( baseImage.getImage().getSnapshotId(), baseImage.getImageId()); } else { // For backwards merge, the prior base image now has the data associated with the newer // snapshot we want to keep. Re-associate this older image with the newer snapshot. // The base snapshot is deleted if everything went well. In case it's not deleted, we // hijack it to preserve a link to the broken image. This makes the image discoverable // so that we can retry the deletion later, yet doesn't corrupt the VM image chain. List<DiskImage> children = DbFacade.getInstance().getDiskImageDao().getAllSnapshotsForParent(topImage.getImageId()); if (!children.isEmpty()) { DiskImage childImage = children.get(0); childImage.setParentId(baseImage.getImageId()); getImageDao().update(childImage.getImage()); } Image oldTopImage = topImage.getImage(); topImage.setImage(baseImage.getImage()); baseImage.setImage(oldTopImage); Guid oldTopSnapshotId = topImage.getImage().getSnapshotId(); topImage.getImage().setSnapshotId(baseImage.getImage().getSnapshotId()); baseImage.getImage().setSnapshotId(oldTopSnapshotId); boolean oldTopIsActive = topImage.getImage().isActive(); topImage.getImage().setActive(baseImage.getImage().isActive()); VolumeClassification baseImageVolumeClassification = VolumeClassification.getVolumeClassificationByActiveFlag(baseImage.getImage().isActive()); topImage.getImage().setVolumeClassification(baseImageVolumeClassification); baseImage.getImage().setActive(oldTopIsActive); VolumeClassification oldTopVolumeClassification = VolumeClassification.getVolumeClassificationByActiveFlag(oldTopIsActive); topImage.getImage().setVolumeClassification(oldTopVolumeClassification); topImage.setSize(baseImage.getSize()); topImage.setImageStatus(ImageStatus.OK); getBaseDiskDao().update(topImage); getImageDao().update(topImage.getImage()); updateDiskImageDynamic(topImage); getBaseDiskDao().update(baseImage); getImageDao().update(baseImage.getImage()); updateVmConfigurationForImageChange( topImage.getImage().getSnapshotId(), baseImage.getImageId(), topImage); updateVmConfigurationForImageRemoval( baseImage.getImage().getSnapshotId(), topImage.getImageId()); } Set<Guid> imagesToUpdate = getParameters().getMergeStatusReturnValue().getImagesToRemove(); if (imagesToUpdate == null) { log.error("Failed to update orphaned images in db: image list could not be retrieved"); return; } for (Guid imageId : imagesToUpdate) { if (removeImages) { getImageDao().remove(imageId); } else { // The (illegal && no-parent && no-children) status indicates an orphaned image. Image image = getImageDao().get(imageId); image.setStatus(ImageStatus.ILLEGAL); image.setParentId(Guid.Empty); getImageDao().update(image); } } }
public static void removeImage(DiskImage diskImage) { DbFacade.getInstance().getImageStorageDomainMapDao().remove(diskImage.getImageId()); DbFacade.getInstance().getDiskImageDynamicDao().remove(diskImage.getImageId()); DbFacade.getInstance().getImageDao().remove(diskImage.getImageId()); }