private void verifySnapshotType(SnapshotInfo snapshotInfo) { if (snapshotInfo.getHypervisorType() == HypervisorType.KVM && snapshotInfo.getDataStore().getRole() != DataStoreRole.Primary) { throw new CloudRuntimeException("For the KVM hypervisor type, you can only revert a volume to a snapshot state if the snapshot " + "resides on primary storage. For other snapshot types, create a volume from the snapshot to recover its data."); } }
private Map<String, String> getSnapshotDetails(SnapshotInfo snapshotInfo) { Map<String, String> snapshotDetails = new HashMap<>(); long storagePoolId = snapshotInfo.getDataStore().getId(); StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePoolId); snapshotDetails.put(DiskTO.STORAGE_HOST, storagePoolVO.getHostAddress()); snapshotDetails.put(DiskTO.STORAGE_PORT, String.valueOf(storagePoolVO.getPort())); long snapshotId = snapshotInfo.getId(); snapshotDetails.put(DiskTO.IQN, getSnapshotProperty(snapshotId, DiskTO.IQN)); snapshotDetails.put(DiskTO.VOLUME_SIZE, String.valueOf(snapshotInfo.getSize())); snapshotDetails.put(DiskTO.SCSI_NAA_DEVICE_ID, getSnapshotProperty(snapshotId, DiskTO.SCSI_NAA_DEVICE_ID)); snapshotDetails.put(DiskTO.CHAP_INITIATOR_USERNAME, getSnapshotProperty(snapshotId, DiskTO.CHAP_INITIATOR_USERNAME)); snapshotDetails.put(DiskTO.CHAP_INITIATOR_SECRET, getSnapshotProperty(snapshotId, DiskTO.CHAP_INITIATOR_SECRET)); snapshotDetails.put(DiskTO.CHAP_TARGET_USERNAME, getSnapshotProperty(snapshotId, DiskTO.CHAP_TARGET_USERNAME)); snapshotDetails.put(DiskTO.CHAP_TARGET_SECRET, getSnapshotProperty(snapshotId, DiskTO.CHAP_TARGET_SECRET)); return snapshotDetails; }
/** * If the underlying storage system needed to create a volume from a snapshot for createVolumeFromSnapshot(SnapshotInfo), then * this is its opportunity to delete that temporary volume and restore properties in snapshot_details to the way they were before the * invocation of createVolumeFromSnapshot(SnapshotInfo). */ private void deleteVolumeFromSnapshot(SnapshotInfo snapshotInfo) { SnapshotDetailsVO snapshotDetails = handleSnapshotDetails(snapshotInfo.getId(), "delete"); try { snapshotInfo.getDataStore().getDriver().createAsync(snapshotInfo.getDataStore(), snapshotInfo, null); } finally { _snapshotDetailsDao.remove(snapshotDetails.getId()); } }
/** * If the underlying storage system is making use of read-only snapshots, this gives the storage system the opportunity to * create a volume from the snapshot so that we can copy the VHD file that should be inside of the snapshot to secondary storage. * * The resultant volume must be writable because we need to resign the SR and the VDI that should be inside of it before we copy * the VHD file to secondary storage. * * If the storage system is using writable snapshots, then nothing need be done by that storage system here because we can just * resign the SR and the VDI that should be inside of the snapshot before copying the VHD file to secondary storage. */ private void createVolumeFromSnapshot(SnapshotInfo snapshotInfo) { SnapshotDetailsVO snapshotDetails = handleSnapshotDetails(snapshotInfo.getId(), "create"); try { snapshotInfo.getDataStore().getDriver().createAsync(snapshotInfo.getDataStore(), snapshotInfo, null); } finally { _snapshotDetailsDao.remove(snapshotDetails.getId()); } }
s_logger.debug("Delete snapshot " + snapshot.getId() + " from image cache store: " + cacheSnap.getDataStore().getName()); cacheSnap.delete();
public SnapshotObjectTO(SnapshotInfo snapshot) { this.path = snapshot.getPath(); this.setId(snapshot.getId()); VolumeInfo vol = snapshot.getBaseVolume(); if (vol != null) { this.volume = (VolumeObjectTO)vol.getTO(); this.setVmName(vol.getAttachedVmName()); } SnapshotInfo parentSnapshot = snapshot.getParent(); ArrayList<String> parentsArry = new ArrayList<String>(); if (parentSnapshot != null) { this.parentSnapshotPath = parentSnapshot.getPath(); while(parentSnapshot != null) { parentsArry.add(parentSnapshot.getPath()); parentSnapshot = parentSnapshot.getParent(); } parents = parentsArry.toArray(new String[parentsArry.size()]); ArrayUtils.reverse(parents); } this.dataStore = snapshot.getDataStore().getTO(); this.setName(snapshot.getName()); this.hypervisorType = snapshot.getHypervisorType(); this.quiescevm = false; }
@Override public boolean deleteSnapshot(SnapshotInfo snapInfo) { snapInfo.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested); AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>(); DeleteSnapshotContext<CommandResult> context = new DeleteSnapshotContext<CommandResult>(null, snapInfo, future); AsyncCallbackDispatcher<SnapshotServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().deleteSnapshotCallback(null, null)).setContext(context); DataStore store = snapInfo.getDataStore(); store.getDriver().deleteAsync(store, snapInfo, caller); SnapshotResult result = null; try { result = future.get(); if (result.isFailed()) { throw new CloudRuntimeException(result.getResult()); } return true; } catch (InterruptedException e) { s_logger.debug("delete snapshot is failed: " + e.toString()); } catch (ExecutionException e) { s_logger.debug("delete snapshot is failed: " + e.toString()); } return false; }
@Override public boolean revertSnapshot(SnapshotInfo snapshot) { SnapshotInfo snapshotOnPrimaryStore = _snapshotFactory.getSnapshot(snapshot.getId(), DataStoreRole.Primary); if (snapshotOnPrimaryStore == null) { throw new CloudRuntimeException("Cannot find an entry for snapshot " + snapshot.getId() + " on primary storage pools"); } PrimaryDataStore store = (PrimaryDataStore)snapshotOnPrimaryStore.getDataStore(); AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>(); RevertSnapshotContext<CommandResult> context = new RevertSnapshotContext<CommandResult>(null, snapshot, future); AsyncCallbackDispatcher<SnapshotServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().revertSnapshotCallback(null, null)).setContext(context); ((PrimaryDataStoreDriver)store.getDriver()).revertSnapshot(snapshot, snapshotOnPrimaryStore, caller); SnapshotResult result = null; try { result = future.get(); if (result.isFailed()) { throw new CloudRuntimeException(result.getResult()); } return true; } catch (InterruptedException e) { s_logger.debug("revert snapshot is failed: " + e.toString()); } catch (ExecutionException e) { s_logger.debug("revert snapshot is failed: " + e.toString()); } return false; }
snapshotOnPrimary = (SnapshotObject)snap.getDataStore().create(snapshot); } catch (Exception e) { s_logger.debug("Failed to create snapshot state on data store due to " + e.getMessage());
private void handleCopyAsyncForSnapshotToVolume(SnapshotInfo srcSnapshotInfo, VolumeInfo destVolumeInfo, AsyncCompletionCallback<CopyCommandResult> callback) { boolean canHandleSrc = canHandle(srcSnapshotInfo); boolean canHandleDest = canHandle(destVolumeInfo); if (canHandleSrc && canHandleDest) { if (srcSnapshotInfo.getDataStore().getId() == destVolumeInfo.getDataStore().getId()) { handleCreateManagedVolumeFromManagedSnapshot(srcSnapshotInfo, destVolumeInfo, callback); } else { String errMsg = "To perform this operation, the source and destination primary storages must be the same."; handleError(errMsg, callback); } } else if (!canHandleSrc && !canHandleDest) { handleError(OPERATION_NOT_SUPPORTED, callback); } else if (canHandleSrc) { handleCreateNonManagedVolumeFromManagedSnapshot(srcSnapshotInfo, destVolumeInfo, callback); } else { handleCreateManagedVolumeFromNonManagedSnapshot(srcSnapshotInfo, destVolumeInfo, callback); } }
@Override public void doInTransactionWithoutResult(TransactionStatus status) { _snapshotDetailsDao.removeDetail(((SnapshotObject)snapshotOnPrimary).getId(), AsyncJob.Constants.MS_ID); DataStore primaryStore = snapshotOnPrimary.getDataStore(); try { SnapshotInfo parent = snapshotOnPrimary.getParent();
needCache = true; SnapshotInfo snapshot = (SnapshotInfo) srcData; srcData = cacheSnapshotChain(snapshot, snapshot.getDataStore().getScope());
_volumeService.grantAccess(snapshotInfo, hostVO, snapshotInfo.getDataStore()); _volumeService.revokeAccess(snapshotInfo, hostVO, snapshotInfo.getDataStore());
try { DataStore snapStore = snapInfo.getDataStore(); long snapVolId = snapInfo.getVolumeId();
destSnapshot.processEvent(Event.OperationSuccessed, copyCmdAnswer); srcSnapshot.processEvent(Snapshot.Event.OperationSucceeded); snapResult = new SnapshotResult(_snapshotFactory.getSnapshot(destSnapshot.getId(), destSnapshot.getDataStore()), copyCmdAnswer); future.complete(snapResult); } catch (Exception e) {
long volumeId = snapshotOnPrimary.getVolumeId(); VolumeVO volumeVO = volumeDao.findById(volumeId); if (((PrimaryDataStoreImpl)snapshotOnPrimaryInfo.getDataStore()).getPoolType() == StoragePoolType.RBD && volumeVO != null) { snapshotSvr.deleteSnapshot(snapshotOnPrimaryInfo);
long snapshotStoragePoolId = snapshotInfo.getDataStore().getId(); DataStore snapshotDataStore = dataStoreMgr.getDataStore(snapshotStoragePoolId, DataStoreRole.Primary); HostVO hostVO = getHostInCluster(volumeStoragePoolVO.getClusterId()); long snapshotStoragePoolId = snapshotInfo.getDataStore().getId(); DataStore snapshotDataStore = dataStoreMgr.getDataStore(snapshotStoragePoolId, DataStoreRole.Primary);
boolean keepGrantedAccess = false; DataStore srcDataStore = snapshotInfo.getDataStore();
DataStore snapStore = snapInfo.getDataStore();
boolean canStorageSystemCreateVolumeFromVolume = canStorageSystemCreateVolumeFromVolume(snapshotInfo.getDataStore().getId());