private void handleQualityOfServiceForVolumeMigration(VolumeInfo volumeInfo, PrimaryDataStoreDriver.QualityOfServiceState qualityOfServiceState) { try { ((PrimaryDataStoreDriver)volumeInfo.getDataStore().getDriver()).handleQualityOfServiceForVolumeMigration(volumeInfo, qualityOfServiceState); } catch (Exception ex) { LOGGER.warn(ex); } }
/** * Clean volumes cache entries (if they exist). */ protected void cleanVolumesCache(VolumeVO volume) { List<VolumeInfo> cacheVols = volFactory.listVolumeOnCache(volume.getId()); if (CollectionUtils.isEmpty(cacheVols)) { return; } for (VolumeInfo volOnCache : cacheVols) { s_logger.info("Delete volume from image cache store: " + volOnCache.getDataStore().getName()); volOnCache.delete(); } }
private Map<String, String> getSourceDetails(VolumeInfo volumeInfo) { Map<String, String> sourceDetails = new HashMap<>(); VolumeVO volumeVO = volumeDao.findById(volumeInfo.getId()); long storagePoolId = volumeVO.getPoolId(); StoragePoolVO storagePoolVO = storagePoolDao.findById(storagePoolId); sourceDetails.put(DiskTO.STORAGE_HOST, storagePoolVO.getHostAddress()); sourceDetails.put(DiskTO.STORAGE_PORT, String.valueOf(storagePoolVO.getPort())); sourceDetails.put(DiskTO.IQN, volumeVO.get_iScsiName()); ChapInfo chapInfo = volService.getChapInfo(volumeInfo, volumeInfo.getDataStore()); if (chapInfo != null) { sourceDetails.put(DiskTO.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername()); sourceDetails.put(DiskTO.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret()); sourceDetails.put(DiskTO.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername()); sourceDetails.put(DiskTO.CHAP_TARGET_SECRET, chapInfo.getTargetSecret()); } return sourceDetails; }
private boolean isVolumeOnManagedStorage(VolumeInfo volumeInfo) { DataStore dataStore = volumeInfo.getDataStore(); if (dataStore.getRole() == DataStoreRole.Primary) { long storagePooldId = dataStore.getId(); StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePooldId); return storagePoolVO.isManaged(); } return false; }
private Map<String, String> getVolumeDetails(VolumeInfo volumeInfo) { long storagePoolId = volumeInfo.getPoolId(); StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePoolId); if (!storagePoolVO.isManaged()) { return null; } Map<String, String> volumeDetails = new HashMap<>(); VolumeVO volumeVO = _volumeDao.findById(volumeInfo.getId()); volumeDetails.put(DiskTO.STORAGE_HOST, storagePoolVO.getHostAddress()); volumeDetails.put(DiskTO.STORAGE_PORT, String.valueOf(storagePoolVO.getPort())); volumeDetails.put(DiskTO.IQN, volumeVO.get_iScsiName()); volumeDetails.put(DiskTO.VOLUME_SIZE, String.valueOf(volumeVO.getSize())); volumeDetails.put(DiskTO.SCSI_NAA_DEVICE_ID, getVolumeProperty(volumeInfo.getId(), DiskTO.SCSI_NAA_DEVICE_ID)); ChapInfo chapInfo = _volumeService.getChapInfo(volumeInfo, volumeInfo.getDataStore()); if (chapInfo != null) { volumeDetails.put(DiskTO.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername()); volumeDetails.put(DiskTO.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret()); volumeDetails.put(DiskTO.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername()); volumeDetails.put(DiskTO.CHAP_TARGET_SECRET, chapInfo.getTargetSecret()); } return volumeDetails; }
/** * Tell the underlying storage plug-in to create a new volume, put it in the VAG of the destination cluster, and * send a command to the destination cluster to create an SR and to attach to the SR from all hosts in the cluster. */ private String handleManagedVolumePreMigration(VolumeInfo volumeInfo, StoragePool storagePool, Host destHost) { final PrimaryDataStoreDriver pdsd = (PrimaryDataStoreDriver)volumeInfo.getDataStore().getDriver(); VolumeDetailVO volumeDetailVo = new VolumeDetailVO(volumeInfo.getId(), PrimaryDataStoreDriver.BASIC_CREATE, Boolean.TRUE.toString(), false); volumeDetailsDao.persist(volumeDetailVo); pdsd.createAsync(volumeInfo.getDataStore(), volumeInfo, null); volumeDetailVo = new VolumeDetailVO(volumeInfo.getId(), PrimaryDataStoreDriver.BASIC_GRANT_ACCESS, Boolean.TRUE.toString(), false); volumeDetailsDao.persist(volumeDetailVo); pdsd.grantAccess(volumeInfo, destHost, volumeInfo.getDataStore()); final Map<String, String> details = new HashMap<>(); final String iqn = getBasicIqn(volumeInfo.getId()); details.put(CreateStoragePoolCommand.DATASTORE_NAME, iqn); details.put(CreateStoragePoolCommand.IQN, iqn); details.put(CreateStoragePoolCommand.STORAGE_HOST, storagePool.getHostAddress()); details.put(CreateStoragePoolCommand.STORAGE_PORT, String.valueOf(storagePool.getPort())); final CreateStoragePoolCommand cmd = new CreateStoragePoolCommand(true, storagePool); cmd.setDetails(details); cmd.setCreateDatastore(true); final Answer answer = agentMgr.easySend(destHost.getId(), cmd); if (answer == null || !answer.getResult()) { String errMsg = "Error interacting with host (related to CreateStoragePoolCommand)" + (StringUtils.isNotBlank(answer.getDetails()) ? ": " + answer.getDetails() : ""); s_logger.error(errMsg); throw new CloudRuntimeException(errMsg); } return iqn; }
private void handleManagedVolumesAfterFailedMigration(Map<VolumeInfo, DataStore> volumeToPool, Host destHost) { for (Map.Entry<VolumeInfo, DataStore> entry : volumeToPool.entrySet()) { VolumeInfo volumeInfo = entry.getKey(); StoragePool storagePool = storagePoolDao.findById(volumeInfo.getPoolId()); if (storagePool.isManaged()) { final Map<String, String> details = new HashMap<>(); details.put(DeleteStoragePoolCommand.DATASTORE_NAME, getBasicIqn(volumeInfo.getId())); final DeleteStoragePoolCommand cmd = new DeleteStoragePoolCommand(); cmd.setDetails(details); cmd.setRemoveDatastore(true); final Answer answer = agentMgr.easySend(destHost.getId(), cmd); if (answer == null || !answer.getResult()) { String errMsg = "Error interacting with host (related to handleManagedVolumesAfterFailedMigration)" + (StringUtils.isNotBlank(answer.getDetails()) ? ": " + answer.getDetails() : ""); s_logger.error(errMsg); // no need to throw an exception here as the calling code is responsible for doing so // regardless of the success or lack thereof concerning this method return; } final PrimaryDataStoreDriver pdsd = (PrimaryDataStoreDriver)volumeInfo.getDataStore().getDriver(); VolumeDetailVO volumeDetailVo = new VolumeDetailVO(volumeInfo.getId(), PrimaryDataStoreDriver.BASIC_REVOKE_ACCESS, Boolean.TRUE.toString(), false); volumeDetailsDao.persist(volumeDetailVo); pdsd.revokeAccess(volumeInfo, destHost, volumeInfo.getDataStore()); volumeDetailVo = new VolumeDetailVO(volumeInfo.getId(), PrimaryDataStoreDriver.BASIC_DELETE_FAILURE, Boolean.TRUE.toString(), false); volumeDetailsDao.persist(volumeDetailVo); pdsd.deleteAsync(volumeInfo.getDataStore(), volumeInfo, null); } } }
private void handleFailedVolumeMigration(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo, HostVO hostVO) { try { _volumeService.revokeAccess(destVolumeInfo, hostVO, destVolumeInfo.getDataStore()); } catch (Exception ex) { LOGGER.warn("Failed to revoke access to the volume with the following ID: " + destVolumeInfo.getId()); } try { VolumeDetailVO volumeDetailVO = new VolumeDetailVO(destVolumeInfo.getId(), PrimaryDataStoreDriver.BASIC_DELETE_BY_FOLDER, Boolean.TRUE.toString(), false); volumeDetailsDao.persist(volumeDetailVO); destVolumeInfo.getDataStore().getDriver().deleteAsync(destVolumeInfo.getDataStore(), destVolumeInfo, null); volumeDetailsDao.removeDetails(srcVolumeInfo.getId()); } catch (Exception ex) { LOGGER.warn(ex.getMessage()); } VolumeVO volumeVO = _volumeDao.findById(srcVolumeInfo.getId()); volumeVO.setPoolId(srcVolumeInfo.getPoolId()); volumeVO.setLastPoolId(srcVolumeInfo.getLastPoolId()); volumeVO.setFolder(srcVolumeInfo.getFolder()); volumeVO.set_iScsiName(srcVolumeInfo.get_iScsiName()); _volumeDao.update(srcVolumeInfo.getId(), volumeVO); }
private void handleCopyAsyncForVolumes(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo, AsyncCompletionCallback<CopyCommandResult> callback) { if (srcVolumeInfo.getState() == Volume.State.Migrating) { if (isVolumeOnManagedStorage(srcVolumeInfo)) { if (destVolumeInfo.getDataStore().getRole() == DataStoreRole.Image || destVolumeInfo.getDataStore().getRole() == DataStoreRole.ImageCache) { handleVolumeCopyFromManagedStorageToSecondaryStorage(srcVolumeInfo, destVolumeInfo, callback); } else if (!isVolumeOnManagedStorage(destVolumeInfo)) { (srcVolumeInfo.getDataStore().getRole() == DataStoreRole.Image || srcVolumeInfo.getDataStore().getRole() == DataStoreRole.ImageCache) && destVolumeInfo.getDataStore().getRole() == DataStoreRole.Primary) { ImageFormat imageFormat = destVolumeInfo.getFormat();
private void handleManagedVolumePostMigration(VolumeInfo volumeInfo, Host srcHost, VolumeObjectTO volumeTO) { final Map<String, String> details = new HashMap<>(); details.put(DeleteStoragePoolCommand.DATASTORE_NAME, volumeInfo.get_iScsiName()); final DeleteStoragePoolCommand cmd = new DeleteStoragePoolCommand(); cmd.setDetails(details); cmd.setRemoveDatastore(true); final Answer answer = agentMgr.easySend(srcHost.getId(), cmd); if (answer == null || !answer.getResult()) { String errMsg = "Error interacting with host (related to DeleteStoragePoolCommand)" + (StringUtils.isNotBlank(answer.getDetails()) ? ": " + answer.getDetails() : ""); s_logger.error(errMsg); throw new CloudRuntimeException(errMsg); } final PrimaryDataStoreDriver pdsd = (PrimaryDataStoreDriver)volumeInfo.getDataStore().getDriver(); pdsd.revokeAccess(volumeInfo, srcHost, volumeInfo.getDataStore()); VolumeDetailVO volumeDetailVo = new VolumeDetailVO(volumeInfo.getId(), PrimaryDataStoreDriver.BASIC_DELETE, Boolean.TRUE.toString(), false); volumeDetailsDao.persist(volumeDetailVo); pdsd.deleteAsync(volumeInfo.getDataStore(), volumeInfo, null); VolumeVO volumeVO = volDao.findById(volumeInfo.getId()); volumeVO.setPath(volumeTO.getPath()); volDao.update(volumeVO.getId(), volumeVO); }
private CopyCmdAnswer copyImageToVolume(DataObject srcDataObject, VolumeInfo destVolumeInfo, HostVO hostVO) { String value = _configDao.getValue(Config.PrimaryStorageDownloadWait.toString()); int primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue())); CopyCommand copyCommand = new CopyCommand(srcDataObject.getTO(), destVolumeInfo.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value()); CopyCmdAnswer copyCmdAnswer; try { _volumeService.grantAccess(destVolumeInfo, hostVO, destVolumeInfo.getDataStore()); Map<String, String> destDetails = getVolumeDetails(destVolumeInfo); copyCommand.setOptions2(destDetails); copyCmdAnswer = (CopyCmdAnswer)_agentMgr.send(hostVO.getId(), copyCommand); } catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) { String msg = "Failed to copy image : "; LOGGER.warn(msg, ex); throw new CloudRuntimeException(msg + ex.getMessage(), ex); } finally { _volumeService.revokeAccess(destVolumeInfo, hostVO, destVolumeInfo.getDataStore()); } VolumeObjectTO volumeObjectTO = (VolumeObjectTO)copyCmdAnswer.getNewData(); volumeObjectTO.setFormat(ImageFormat.QCOW2); return copyCmdAnswer; }
destVolumeInfo.getDataStore().getDriver().createAsync(destVolumeInfo.getDataStore(), destVolumeInfo, null); destVolumeInfo = _volumeDataFactory.getVolume(destVolumeInfo.getId(), destVolumeInfo.getDataStore());
@Override public AsyncCallFuture<VolumeApiResult> resize(VolumeInfo volume) { AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>(); VolumeApiResult result = new VolumeApiResult(volume); try { volume.processEvent(Event.ResizeRequested); } catch (Exception e) { s_logger.debug("Failed to change state to resize", e); result.setResult(e.toString()); future.complete(result); return future; } CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volume, future); AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().resizeVolumeCallback(caller, context)).setContext(context); try { volume.getDataStore().getDriver().resize(volume, caller); } catch (Exception e) { s_logger.debug("Failed to change state to resize", e); result.setResult(e.toString()); future.complete(result); } return future; }
destVolumeInfo.getDataStore().getUri(), true, StorageManager.KvmStorageOfflineMigrationWait.value(), true); _volumeService.grantAccess(srcVolumeInfo, hostVO, srcVolumeInfo.getDataStore()); _volumeService.revokeAccess(srcVolumeInfo, hostVO, srcVolumeInfo.getDataStore());
protected AsyncCallFuture<VolumeApiResult> copyVolumeFromPrimaryToImage(VolumeInfo srcVolume, DataStore destStore) { AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>(); VolumeApiResult res = new VolumeApiResult(srcVolume); VolumeInfo destVolume = null; try { destVolume = (VolumeInfo)destStore.create(srcVolume); srcVolume.processEvent(Event.MigrationRequested); // this is just used for locking that src volume record in DB to avoid using lock destVolume.processEventOnly(Event.CreateOnlyRequested); CopyVolumeContext<VolumeApiResult> context = new CopyVolumeContext<VolumeApiResult>(null, future, srcVolume, destVolume, destStore); AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().copyVolumeFromPrimaryToImageCallback(null, null)).setContext(context); motionSrv.copyAsync(srcVolume, destVolume, caller); return future; } catch (Exception e) { s_logger.error("failed to copy volume to image store", e); if (destVolume != null) { destVolume.getDataStore().delete(destVolume); } srcVolume.processEvent(Event.OperationFailed); // unlock source volume record res.setResult(e.toString()); future.complete(res); return future; } }
private void handleVolumeMigrationForKVM(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo) { VirtualMachine vm = srcVolumeInfo.getAttachedVM(); if (vm != null && vm.getState() != VirtualMachine.State.Stopped) { throw new CloudRuntimeException("Currently, if a volume to migrate from non-managed storage to managed storage on KVM is attached to " + "a VM, the VM must be in the Stopped state."); } destVolumeInfo.getDataStore().getDriver().createAsync(destVolumeInfo.getDataStore(), destVolumeInfo, null); VolumeVO volumeVO = _volumeDao.findById(destVolumeInfo.getId()); volumeVO.setPath(volumeVO.get_iScsiName()); _volumeDao.update(volumeVO.getId(), volumeVO); destVolumeInfo = _volumeDataFactory.getVolume(destVolumeInfo.getId(), destVolumeInfo.getDataStore()); long srcStoragePoolId = srcVolumeInfo.getPoolId(); StoragePoolVO srcStoragePoolVO = _storagePoolDao.findById(srcStoragePoolId); HostVO hostVO; if (srcStoragePoolVO.getClusterId() != null) { hostVO = getHostInCluster(srcStoragePoolVO.getClusterId()); } else { hostVO = getHost(destVolumeInfo.getDataCenterId(), HypervisorType.KVM, false); } // migrate the volume via the hypervisor migrateVolumeForKVM(srcVolumeInfo, destVolumeInfo, hostVO, "Unable to migrate the volume from non-managed storage to managed storage"); volumeVO = _volumeDao.findById(destVolumeInfo.getId()); volumeVO.setFormat(ImageFormat.QCOW2); _volumeDao.update(volumeVO.getId(), volumeVO); }
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); } }
protected Void copyVolumeFromImageToPrimaryCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CopyVolumeContext<VolumeApiResult> context) { VolumeInfo srcVolume = context.srcVolume; VolumeInfo destVolume = context.destVolume; CopyCommandResult result = callback.getResult(); AsyncCallFuture<VolumeApiResult> future = context.future; VolumeApiResult res = new VolumeApiResult(destVolume); try { if (result.isFailed()) { destVolume.processEvent(Event.OperationFailed); srcVolume.processEvent(Event.OperationFailed); res.setResult(result.getResult()); future.complete(res); return null; } srcVolume.processEvent(Event.OperationSuccessed); destVolume.processEvent(Event.OperationSuccessed, result.getAnswer()); srcVolume.getDataStore().delete(srcVolume); future.complete(res); } catch (Exception e) { res.setResult(e.toString()); future.complete(res); } return null; }
public VolumeObjectTO(VolumeInfo volume) { uuid = volume.getUuid(); path = volume.getPath(); accountId = volume.getAccountId(); if (volume.getDataStore() != null) { dataStore = volume.getDataStore().getTO(); } else { dataStore = null; } vmName = volume.getAttachedVmName(); size = volume.getSize(); setVolumeId(volume.getId()); chainInfo = volume.getChainInfo(); volumeType = volume.getVolumeType(); name = volume.getName(); setId(volume.getId()); format = volume.getFormat(); provisioningType = volume.getProvisioningType(); bytesReadRate = volume.getBytesReadRate(); bytesWriteRate = volume.getBytesWriteRate(); iopsReadRate = volume.getIopsReadRate(); iopsWriteRate = volume.getIopsWriteRate(); cacheMode = volume.getCacheMode(); hypervisorType = volume.getHypervisorType(); setDeviceId(volume.getDeviceId()); }
destVolumeInfo = _volumeDataFactory.getVolume(destVolumeInfo.getId(), destVolumeInfo.getDataStore());