Github user syed commented on a diff in the pull request: https://github.com/apache/cloudstack/pull/1600#discussion_r77259343 --- Diff: engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java --- @@ -380,6 +513,122 @@ private void handleCreateTemplateFromSnapshot(SnapshotInfo snapshotInfo, Templat } /** + * Creates a volume on the storage from a snapshot that resides on the secondary storage (archived snapshot). + * @param snapshotInfo snapshot on secondary + * @param volumeInfo volume to be created on the storage + * @param callback for async + */ + private void handleCreateVolumeFromSnapshotOnSecondaryStorage(SnapshotInfo snapshotInfo, VolumeInfo volumeInfo, AsyncCompletionCallback<CopyCommandResult> callback) { + + // at this point, the snapshotInfo and volumeInfo should have the same disk offering ID (so either one should be OK to get a DiskOfferingVO instance) + DiskOfferingVO diskOffering = _diskOfferingDao.findByIdIncludingRemoved(volumeInfo.getDiskOfferingId()); + SnapshotVO snapshot = _snapshotDao.findById(snapshotInfo.getId()); + DataStore destDataStore = volumeInfo.getDataStore(); + + // update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage) + _volumeService.updateHypervisorSnapshotReserveForVolume(diskOffering, volumeInfo.getId(), snapshot.getHypervisorType()); + + + CopyCmdAnswer copyCmdAnswer = null; + String errMsg = null; + + HostVO hostVO = null; + try { + + //create a volume on the storage + AsyncCallFuture<VolumeApiResult> future = _volumeService.createVolumeAsync(volumeInfo, volumeInfo.getDataStore()); + VolumeApiResult result = future.get(); + + if (result.isFailed()) { + LOGGER.warn("Failed to create a volume: " + result.getResult()); + throw new CloudRuntimeException(result.getResult()); + } + + volumeInfo = _volumeDataFactory.getVolume(volumeInfo.getId(), volumeInfo.getDataStore()); + + volumeInfo.processEvent(Event.MigrationRequested); + + volumeInfo = _volumeDataFactory.getVolume(volumeInfo.getId(), volumeInfo.getDataStore()); + + hostVO = getHost(snapshotInfo.getDataCenterId(), false); + + //copy the volume from secondary via the hypervisor + copyCmdAnswer = performCopyOfVdi(volumeInfo, snapshotInfo, hostVO); + + if (copyCmdAnswer == null || !copyCmdAnswer.getResult()) { + if (copyCmdAnswer != null && !StringUtils.isEmpty(copyCmdAnswer.getDetails())) { + errMsg = copyCmdAnswer.getDetails(); + } + else { + errMsg = "Unable to create volume from snapshot"; + } + } + } + catch (Exception ex) { + errMsg = ex.getMessage() != null ? ex.getMessage() : "Copy operation failed in 'StorageSystemDataMotionStrategy.handleCreateVolumeFromSnapshotBothOnStorageSystem'"; + } finally { + + // detach and remove access after the volume is created + DiskTO disk = new DiskTO(volumeInfo.getTO(), volumeInfo.getDeviceId(), volumeInfo.getPath(), volumeInfo.getVolumeType()); + DettachCommand cmd = new DettachCommand(disk, null); + long storagePoolId = volumeInfo.getPoolId(); + StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId); + + cmd.setManaged(true); + cmd.setStorageHost(storagePool.getHostAddress()); + cmd.setStoragePort(storagePool.getPort()); + cmd.set_iScsiName(volumeInfo.get_iScsiName()); + + try { + DettachAnswer dettachAnswer = (DettachAnswer) _agentMgr.send(hostVO.getId(), cmd); + + if (!dettachAnswer.getResult()) { + throw new CloudRuntimeException("Error detaching volume:" + dettachAnswer.getDetails()); + } + + } catch (Exception e) { + LOGGER.warn("Error detaching volume " + volumeInfo.getId() + " Error: " + e.getMessage()); + } + + _volumeService.revokeAccess(volumeInfo, hostVO, destDataStore); --- End diff -- moved to a common function
--- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---