Search in sources :

Example 26 with CopyCommand

use of org.apache.cloudstack.storage.command.CopyCommand in project cloudstack by apache.

the class KvmNonManagedStorageDataMotionStrategy method sendCopyCommand.

/**
 * Sends the CopyCommand to migrate the template to the dest host.
 */
protected Answer sendCopyCommand(Host destHost, TemplateObjectTO sourceTemplate, TemplateObjectTO destTemplate, DataStore destDataStore) {
    boolean executeInSequence = virtualMachineManager.getExecuteInSequence(HypervisorType.KVM);
    CopyCommand copyCommand = new CopyCommand(sourceTemplate, destTemplate, StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value(), executeInSequence);
    try {
        Answer copyCommandAnswer = agentManager.send(destHost.getId(), copyCommand);
        logInCaseOfTemplateCopyFailure(copyCommandAnswer, sourceTemplate, destDataStore);
        return copyCommandAnswer;
    } catch (AgentUnavailableException | OperationTimedoutException e) {
        throw new CloudRuntimeException(generateFailToCopyTemplateMessage(sourceTemplate, destDataStore), e);
    }
}
Also used : Answer(com.cloud.agent.api.Answer) OperationTimedoutException(com.cloud.exception.OperationTimedoutException) CopyCommand(org.apache.cloudstack.storage.command.CopyCommand) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException)

Example 27 with CopyCommand

use of org.apache.cloudstack.storage.command.CopyCommand in project cloudstack by apache.

the class StorageSystemDataMotionStrategy method handleCopyAsyncToSecondaryStorage.

/**
 * This function is responsible for copying a snapshot from managed storage to secondary storage. This is used in the following two cases:
 * 1) When creating a template from a snapshot
 * 2) When createSnapshot is called with location=SECONDARY
 *
 * @param snapshotInfo source snapshot
 * @param destData destination (can be template or snapshot)
 * @param callback callback for async
 */
private void handleCopyAsyncToSecondaryStorage(SnapshotInfo snapshotInfo, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
    String errMsg = null;
    CopyCmdAnswer copyCmdAnswer = null;
    boolean usingBackendSnapshot = false;
    try {
        snapshotInfo.processEvent(Event.CopyingRequested);
        HostVO hostVO = getHost(snapshotInfo);
        boolean needCache = needCacheStorage(snapshotInfo, destData);
        DataObject destOnStore = destData;
        if (needCache) {
            // creates an object in the DB for data to be cached
            Scope selectedScope = pickCacheScopeForCopy(snapshotInfo, destData);
            destOnStore = cacheMgr.getCacheObject(snapshotInfo, selectedScope);
            destOnStore.processEvent(Event.CreateOnlyRequested);
        }
        usingBackendSnapshot = usingBackendSnapshotFor(snapshotInfo);
        if (usingBackendSnapshot) {
            final boolean computeClusterSupportsVolumeClone;
            // only XenServer, VMware, and KVM are currently supported
            if (HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType())) {
                computeClusterSupportsVolumeClone = clusterDao.getSupportsResigning(hostVO.getClusterId());
            } else if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType()) || HypervisorType.KVM.equals(snapshotInfo.getHypervisorType())) {
                computeClusterSupportsVolumeClone = true;
            } else {
                throw new CloudRuntimeException("Unsupported hypervisor type");
            }
            if (!computeClusterSupportsVolumeClone) {
                String noSupportForResignErrMsg = "Unable to locate an applicable host with which to perform a resignature operation : Cluster ID = " + hostVO.getClusterId();
                LOGGER.warn(noSupportForResignErrMsg);
                throw new CloudRuntimeException(noSupportForResignErrMsg);
            }
        }
        String vmdk = null;
        String uuid = null;
        boolean keepGrantedAccess = false;
        DataStore srcDataStore = snapshotInfo.getDataStore();
        StoragePoolVO storagePoolVO = _storagePoolDao.findById(srcDataStore.getId());
        if (HypervisorType.KVM.equals(snapshotInfo.getHypervisorType()) && storagePoolVO.getPoolType() == StoragePoolType.PowerFlex) {
            usingBackendSnapshot = false;
        }
        if (usingBackendSnapshot) {
            createVolumeFromSnapshot(snapshotInfo);
            if (HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType()) || HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
                keepGrantedAccess = HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType());
                Map<String, String> extraDetails = null;
                if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
                    extraDetails = new HashMap<>();
                    String extraDetailsVmdk = getSnapshotProperty(snapshotInfo.getId(), DiskTO.VMDK);
                    extraDetails.put(DiskTO.VMDK, extraDetailsVmdk);
                    extraDetails.put(DiskTO.TEMPLATE_RESIGN, Boolean.TRUE.toString());
                }
                copyCmdAnswer = performResignature(snapshotInfo, hostVO, extraDetails, keepGrantedAccess);
                // If using VMware, have the host rescan its software HBA if dynamic discovery is in use.
                if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
                    String iqn = getSnapshotProperty(snapshotInfo.getId(), DiskTO.IQN);
                    disconnectHostFromVolume(hostVO, srcDataStore.getId(), iqn);
                }
                verifyCopyCmdAnswer(copyCmdAnswer, snapshotInfo);
                vmdk = copyCmdAnswer.getNewData().getPath();
                uuid = UUID.randomUUID().toString();
            }
        }
        int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
        CopyCommand copyCommand = new CopyCommand(snapshotInfo.getTO(), destOnStore.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value());
        try {
            if (!keepGrantedAccess) {
                _volumeService.grantAccess(snapshotInfo, hostVO, srcDataStore);
            }
            Map<String, String> srcDetails = getSnapshotDetails(snapshotInfo);
            if (isForVMware(destData)) {
                srcDetails.put(DiskTO.VMDK, vmdk);
                srcDetails.put(DiskTO.UUID, uuid);
                if (destData instanceof TemplateInfo) {
                    VMTemplateVO templateDataStoreVO = _vmTemplateDao.findById(destData.getId());
                    templateDataStoreVO.setUniqueName(uuid);
                    _vmTemplateDao.update(destData.getId(), templateDataStoreVO);
                }
            }
            copyCommand.setOptions(srcDetails);
            copyCmdAnswer = (CopyCmdAnswer) agentManager.send(hostVO.getId(), copyCommand);
            if (!copyCmdAnswer.getResult()) {
                errMsg = copyCmdAnswer.getDetails();
                LOGGER.warn(errMsg);
                throw new CloudRuntimeException(errMsg);
            }
            if (needCache) {
                // If cached storage was needed (in case of object store as secondary
                // storage), at this point, the data has been copied from the primary
                // to the NFS cache by the hypervisor. We now invoke another copy
                // command to copy this data from cache to secondary storage. We
                // then clean up the cache.
                destOnStore.processEvent(Event.OperationSuccessed, copyCmdAnswer);
                CopyCommand cmd = new CopyCommand(destOnStore.getTO(), destData.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value());
                EndPoint ep = selector.select(destOnStore, destData);
                if (ep == null) {
                    errMsg = "No remote endpoint to send command, check if host or SSVM is down";
                    LOGGER.error(errMsg);
                    copyCmdAnswer = new CopyCmdAnswer(errMsg);
                } else {
                    copyCmdAnswer = (CopyCmdAnswer) ep.sendMessage(cmd);
                }
                // clean up snapshot copied to staging
                cacheMgr.deleteCacheObject(destOnStore);
            }
        } catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
            String msg = "Failed to create template from snapshot (Snapshot ID = " + snapshotInfo.getId() + ") : ";
            LOGGER.warn(msg, ex);
            throw new CloudRuntimeException(msg + ex.getMessage(), ex);
        } finally {
            _volumeService.revokeAccess(snapshotInfo, hostVO, srcDataStore);
            // If using VMware, have the host rescan its software HBA if dynamic discovery is in use.
            if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
                String iqn = getSnapshotProperty(snapshotInfo.getId(), DiskTO.IQN);
                disconnectHostFromVolume(hostVO, srcDataStore.getId(), iqn);
            }
            if (copyCmdAnswer == null || !copyCmdAnswer.getResult()) {
                if (copyCmdAnswer != null && StringUtils.isNotEmpty(copyCmdAnswer.getDetails())) {
                    errMsg = copyCmdAnswer.getDetails();
                    if (needCache) {
                        cacheMgr.deleteCacheObject(destOnStore);
                    }
                } else {
                    errMsg = "Unable to create template from snapshot";
                }
            }
            try {
                if (StringUtils.isEmpty(errMsg)) {
                    snapshotInfo.processEvent(Event.OperationSuccessed);
                } else {
                    snapshotInfo.processEvent(Event.OperationFailed);
                }
            } catch (Exception ex) {
                LOGGER.warn("Error processing snapshot event: " + ex.getMessage(), ex);
            }
        }
    } catch (Exception ex) {
        errMsg = ex.getMessage();
        throw new CloudRuntimeException(errMsg);
    } finally {
        if (usingBackendSnapshot) {
            deleteVolumeFromSnapshot(snapshotInfo);
        }
        if (copyCmdAnswer == null) {
            copyCmdAnswer = new CopyCmdAnswer(errMsg);
        }
        CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
        result.setResult(errMsg);
        callback.complete(result);
    }
}
Also used : OperationTimedoutException(com.cloud.exception.OperationTimedoutException) CopyCommand(org.apache.cloudstack.storage.command.CopyCommand) VMTemplateVO(com.cloud.storage.VMTemplateVO) EndPoint(org.apache.cloudstack.engine.subsystem.api.storage.EndPoint) HostVO(com.cloud.host.HostVO) EndPoint(org.apache.cloudstack.engine.subsystem.api.storage.EndPoint) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) OperationTimedoutException(com.cloud.exception.OperationTimedoutException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) TemplateInfo(org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo) DataObject(org.apache.cloudstack.engine.subsystem.api.storage.DataObject) Scope(org.apache.cloudstack.engine.subsystem.api.storage.Scope) ClusterScope(org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope) ZoneScope(org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope) HostScope(org.apache.cloudstack.engine.subsystem.api.storage.HostScope) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) DataStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore) VMTemplateStoragePoolVO(com.cloud.storage.VMTemplateStoragePoolVO) StoragePoolVO(org.apache.cloudstack.storage.datastore.db.StoragePoolVO) CopyCommandResult(org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer)

Example 28 with CopyCommand

use of org.apache.cloudstack.storage.command.CopyCommand in project cloudstack by apache.

the class StorageSystemDataMotionStrategy method performCopyOfVdi.

/**
 * Copies data from secondary storage to a primary volume
 * @param volumeInfo The primary volume
 * @param snapshotInfo  destination of the copy
 * @param hostVO the host used to copy the data
 * @return result of the copy
 */
private CopyCmdAnswer performCopyOfVdi(VolumeInfo volumeInfo, SnapshotInfo snapshotInfo, HostVO hostVO) {
    Snapshot.LocationType locationType = snapshotInfo.getLocationType();
    int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
    DataObject srcData = snapshotInfo;
    CopyCmdAnswer copyCmdAnswer = null;
    DataObject cacheData = null;
    boolean needCacheStorage = needCacheStorage(snapshotInfo, volumeInfo);
    if (needCacheStorage) {
        cacheData = cacheSnapshotChain(snapshotInfo, new ZoneScope(volumeInfo.getDataCenterId()));
        srcData = cacheData;
    }
    CopyCommand copyCommand = new CopyCommand(srcData.getTO(), volumeInfo.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value());
    try {
        if (Snapshot.LocationType.PRIMARY.equals(locationType)) {
            _volumeService.grantAccess(snapshotInfo, hostVO, snapshotInfo.getDataStore());
            Map<String, String> srcDetails = getSnapshotDetails(snapshotInfo);
            copyCommand.setOptions(srcDetails);
        }
        _volumeService.grantAccess(volumeInfo, hostVO, volumeInfo.getDataStore());
        Map<String, String> destDetails = getVolumeDetails(volumeInfo);
        copyCommand.setOptions2(destDetails);
        copyCmdAnswer = (CopyCmdAnswer) agentManager.send(hostVO.getId(), copyCommand);
    } catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
        String msg = "Failed to perform VDI copy : ";
        LOGGER.warn(msg, ex);
        throw new CloudRuntimeException(msg + ex.getMessage(), ex);
    } finally {
        if (Snapshot.LocationType.PRIMARY.equals(locationType)) {
            _volumeService.revokeAccess(snapshotInfo, hostVO, snapshotInfo.getDataStore());
        }
        _volumeService.revokeAccess(volumeInfo, hostVO, volumeInfo.getDataStore());
        if (needCacheStorage && copyCmdAnswer != null && copyCmdAnswer.getResult()) {
            cacheMgr.deleteCacheObject(cacheData);
        }
    }
    return copyCmdAnswer;
}
Also used : OperationTimedoutException(com.cloud.exception.OperationTimedoutException) CopyCommand(org.apache.cloudstack.storage.command.CopyCommand) EndPoint(org.apache.cloudstack.engine.subsystem.api.storage.EndPoint) ZoneScope(org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope) Snapshot(com.cloud.storage.Snapshot) DataObject(org.apache.cloudstack.engine.subsystem.api.storage.DataObject) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer)

Example 29 with CopyCommand

use of org.apache.cloudstack.storage.command.CopyCommand in project cloudstack by apache.

the class StorageSystemDataMotionStrategy method handleCreateTemplateFromManagedVolume.

private void handleCreateTemplateFromManagedVolume(VolumeInfo volumeInfo, TemplateInfo templateInfo, AsyncCompletionCallback<CopyCommandResult> callback) {
    boolean srcVolumeDetached = volumeInfo.getAttachedVM() == null;
    String errMsg = null;
    CopyCmdAnswer copyCmdAnswer = null;
    try {
        StoragePoolVO storagePoolVO = _storagePoolDao.findById(volumeInfo.getPoolId());
        if (!ImageFormat.QCOW2.equals(volumeInfo.getFormat()) && !(ImageFormat.RAW.equals(volumeInfo.getFormat()) && StoragePoolType.PowerFlex == storagePoolVO.getPoolType())) {
            throw new CloudRuntimeException("When using managed storage, you can only create a template from a volume on KVM currently.");
        }
        volumeInfo.processEvent(Event.MigrationRequested);
        HostVO hostVO = getHost(volumeInfo.getDataCenterId(), HypervisorType.KVM, false);
        DataStore srcDataStore = volumeInfo.getDataStore();
        int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
        CopyCommand copyCommand = new CopyCommand(volumeInfo.getTO(), templateInfo.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value());
        try {
            handleQualityOfServiceForVolumeMigration(volumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.MIGRATION);
            if (srcVolumeDetached || StoragePoolType.PowerFlex == storagePoolVO.getPoolType()) {
                _volumeService.grantAccess(volumeInfo, hostVO, srcDataStore);
            }
            Map<String, String> srcDetails = getVolumeDetails(volumeInfo);
            copyCommand.setOptions(srcDetails);
            copyCmdAnswer = (CopyCmdAnswer) agentManager.send(hostVO.getId(), copyCommand);
            if (!copyCmdAnswer.getResult()) {
                errMsg = copyCmdAnswer.getDetails();
                LOGGER.warn(errMsg);
                throw new CloudRuntimeException(errMsg);
            }
            VMTemplateVO vmTemplateVO = _vmTemplateDao.findById(templateInfo.getId());
            vmTemplateVO.setHypervisorType(HypervisorType.KVM);
            _vmTemplateDao.update(vmTemplateVO.getId(), vmTemplateVO);
        } catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
            String msg = "Failed to create template from volume (Volume ID = " + volumeInfo.getId() + ") : ";
            LOGGER.warn(msg, ex);
            throw new CloudRuntimeException(msg + ex.getMessage(), ex);
        } finally {
            if (srcVolumeDetached || StoragePoolType.PowerFlex == storagePoolVO.getPoolType()) {
                try {
                    _volumeService.revokeAccess(volumeInfo, hostVO, srcDataStore);
                } catch (Exception ex) {
                    LOGGER.warn("Error revoking access to volume (Volume ID = " + volumeInfo.getId() + "): " + ex.getMessage(), ex);
                }
            }
            handleQualityOfServiceForVolumeMigration(volumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.NO_MIGRATION);
            if (copyCmdAnswer == null || !copyCmdAnswer.getResult()) {
                if (copyCmdAnswer != null && StringUtils.isNotEmpty(copyCmdAnswer.getDetails())) {
                    errMsg = copyCmdAnswer.getDetails();
                } else {
                    errMsg = "Unable to create template from volume";
                }
            }
            try {
                if (StringUtils.isEmpty(errMsg)) {
                    volumeInfo.processEvent(Event.OperationSuccessed);
                } else {
                    volumeInfo.processEvent(Event.OperationFailed);
                }
            } catch (Exception ex) {
                LOGGER.warn("Error processing snapshot event: " + ex.getMessage(), ex);
            }
        }
    } catch (Exception ex) {
        errMsg = ex.getMessage();
        throw new CloudRuntimeException(errMsg);
    } finally {
        if (copyCmdAnswer == null) {
            copyCmdAnswer = new CopyCmdAnswer(errMsg);
        }
        CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
        result.setResult(errMsg);
        callback.complete(result);
    }
}
Also used : OperationTimedoutException(com.cloud.exception.OperationTimedoutException) CopyCommand(org.apache.cloudstack.storage.command.CopyCommand) VMTemplateVO(com.cloud.storage.VMTemplateVO) HostVO(com.cloud.host.HostVO) EndPoint(org.apache.cloudstack.engine.subsystem.api.storage.EndPoint) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) OperationTimedoutException(com.cloud.exception.OperationTimedoutException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) DataStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore) VMTemplateStoragePoolVO(com.cloud.storage.VMTemplateStoragePoolVO) StoragePoolVO(org.apache.cloudstack.storage.datastore.db.StoragePoolVO) CopyCommandResult(org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer)

Aggregations

CopyCommand (org.apache.cloudstack.storage.command.CopyCommand)29 EndPoint (org.apache.cloudstack.engine.subsystem.api.storage.EndPoint)17 Answer (com.cloud.agent.api.Answer)16 CopyCmdAnswer (org.apache.cloudstack.storage.command.CopyCmdAnswer)14 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)13 DataObject (org.apache.cloudstack.engine.subsystem.api.storage.DataObject)9 AgentUnavailableException (com.cloud.exception.AgentUnavailableException)8 OperationTimedoutException (com.cloud.exception.OperationTimedoutException)8 DataStore (org.apache.cloudstack.engine.subsystem.api.storage.DataStore)8 RemoteHostEndPoint (org.apache.cloudstack.storage.RemoteHostEndPoint)8 CopyCommandResult (org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult)7 ZoneScope (org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope)7 MigrateVolumeAnswer (com.cloud.agent.api.storage.MigrateVolumeAnswer)6 DataStoreTO (com.cloud.agent.api.to.DataStoreTO)6 DataTO (com.cloud.agent.api.to.DataTO)6 NfsTO (com.cloud.agent.api.to.NfsTO)6 HostVO (com.cloud.host.HostVO)6 TemplateObjectTO (org.apache.cloudstack.storage.to.TemplateObjectTO)6 ClusterScope (org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope)5 HostScope (org.apache.cloudstack.engine.subsystem.api.storage.HostScope)5