Search in sources :

Example 21 with StoragePoolVO

use of org.apache.cloudstack.storage.datastore.db.StoragePoolVO in project cloudstack by apache.

the class StorageSystemDataMotionStrategy method handleCreateNonManagedVolumeFromManagedSnapshot.

private void handleCreateNonManagedVolumeFromManagedSnapshot(SnapshotInfo snapshotInfo, VolumeInfo volumeInfo, AsyncCompletionCallback<CopyCommandResult> callback) {
    if (!HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType())) {
        String errMsg = "Creating a volume on non-managed storage from a snapshot on managed storage is currently only supported with XenServer.";
        handleError(errMsg, callback);
    }
    long volumeStoragePoolId = volumeInfo.getDataStore().getId();
    StoragePoolVO volumeStoragePoolVO = _storagePoolDao.findById(volumeStoragePoolId);
    if (volumeStoragePoolVO.getClusterId() == null) {
        String errMsg = "To create a non-managed volume from a managed snapshot, the destination storage pool must be cluster scoped.";
        handleError(errMsg, callback);
    }
    String errMsg = null;
    CopyCmdAnswer copyCmdAnswer = null;
    boolean usingBackendSnapshot = false;
    try {
        snapshotInfo.processEvent(Event.CopyingRequested);
        usingBackendSnapshot = usingBackendSnapshotFor(snapshotInfo);
        if (usingBackendSnapshot) {
            boolean computeClusterSupportsVolumeClone = clusterDao.getSupportsResigning(volumeStoragePoolVO.getClusterId());
            if (!computeClusterSupportsVolumeClone) {
                String noSupportForResignErrMsg = "Unable to locate an applicable host with which to perform a resignature operation : Cluster ID = " + volumeStoragePoolVO.getClusterId();
                LOGGER.warn(noSupportForResignErrMsg);
                throw new CloudRuntimeException(noSupportForResignErrMsg);
            }
            createVolumeFromSnapshot(snapshotInfo);
            HostVO hostVO = getHost(snapshotInfo.getDataCenterId(), HypervisorType.XenServer, true);
            copyCmdAnswer = performResignature(snapshotInfo, hostVO, null, true);
            verifyCopyCmdAnswer(copyCmdAnswer, snapshotInfo);
        }
        int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
        CopyCommand copyCommand = new CopyCommand(snapshotInfo.getTO(), volumeInfo.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value());
        HostVO hostVO = getHostInCluster(volumeStoragePoolVO.getClusterId());
        if (!usingBackendSnapshot) {
            long snapshotStoragePoolId = snapshotInfo.getDataStore().getId();
            DataStore snapshotDataStore = dataStoreMgr.getDataStore(snapshotStoragePoolId, DataStoreRole.Primary);
            _volumeService.grantAccess(snapshotInfo, hostVO, snapshotDataStore);
        }
        Map<String, String> srcDetails = getSnapshotDetails(snapshotInfo);
        copyCommand.setOptions(srcDetails);
        copyCmdAnswer = (CopyCmdAnswer) agentManager.send(hostVO.getId(), copyCommand);
        if (!copyCmdAnswer.getResult()) {
            errMsg = copyCmdAnswer.getDetails();
            LOGGER.warn(errMsg);
            throw new CloudRuntimeException(errMsg);
        }
    } catch (Exception ex) {
        errMsg = "Copy operation failed in 'StorageSystemDataMotionStrategy.handleCreateNonManagedVolumeFromManagedSnapshot': " + ex.getMessage();
        throw new CloudRuntimeException(errMsg);
    } finally {
        try {
            HostVO hostVO = getHostInCluster(volumeStoragePoolVO.getClusterId());
            long snapshotStoragePoolId = snapshotInfo.getDataStore().getId();
            DataStore snapshotDataStore = dataStoreMgr.getDataStore(snapshotStoragePoolId, DataStoreRole.Primary);
            _volumeService.revokeAccess(snapshotInfo, hostVO, snapshotDataStore);
        } catch (Exception e) {
            LOGGER.debug("Failed to revoke access from dest volume", e);
        }
        if (usingBackendSnapshot) {
            deleteVolumeFromSnapshot(snapshotInfo);
        }
        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);
        }
        if (copyCmdAnswer == null) {
            copyCmdAnswer = new CopyCmdAnswer(errMsg);
        }
        CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
        result.setResult(errMsg);
        callback.complete(result);
    }
}
Also used : CopyCommand(org.apache.cloudstack.storage.command.CopyCommand) 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) 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 22 with StoragePoolVO

use of org.apache.cloudstack.storage.datastore.db.StoragePoolVO in project cloudstack by apache.

the class StorageSystemDataMotionStrategy method handleVolumeMigrationFromManagedStorageToNonManagedStorage.

private void handleVolumeMigrationFromManagedStorageToNonManagedStorage(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo, AsyncCompletionCallback<CopyCommandResult> callback) {
    String errMsg = null;
    try {
        if (!ImageFormat.QCOW2.equals(srcVolumeInfo.getFormat())) {
            throw new CloudRuntimeException("Currently, only the KVM hypervisor type is supported for the migration of a volume " + "from managed storage to non-managed storage.");
        }
        HypervisorType hypervisorType = HypervisorType.KVM;
        VirtualMachine vm = srcVolumeInfo.getAttachedVM();
        if (vm != null && vm.getState() != VirtualMachine.State.Stopped) {
            throw new CloudRuntimeException("Currently, if a volume to migrate from managed storage to non-managed storage is attached to " + "a VM, the VM must be in the Stopped state.");
        }
        long destStoragePoolId = destVolumeInfo.getPoolId();
        StoragePoolVO destStoragePoolVO = _storagePoolDao.findById(destStoragePoolId);
        HostVO hostVO;
        if (destStoragePoolVO.getClusterId() != null) {
            hostVO = getHostInCluster(destStoragePoolVO.getClusterId());
        } else {
            hostVO = getHost(destVolumeInfo.getDataCenterId(), hypervisorType, false);
        }
        setCertainVolumeValuesNull(destVolumeInfo.getId());
        // migrate the volume via the hypervisor
        String path = migrateVolumeForKVM(srcVolumeInfo, destVolumeInfo, hostVO, "Unable to migrate the volume from managed storage to non-managed storage");
        updateVolumePath(destVolumeInfo.getId(), path);
    } catch (Exception ex) {
        errMsg = "Migration operation failed in 'StorageSystemDataMotionStrategy.handleVolumeMigrationFromManagedStorageToNonManagedStorage': " + ex.getMessage();
        throw new CloudRuntimeException(errMsg);
    } finally {
        CopyCmdAnswer copyCmdAnswer;
        if (errMsg != null) {
            copyCmdAnswer = new CopyCmdAnswer(errMsg);
        } else {
            destVolumeInfo = _volumeDataFactory.getVolume(destVolumeInfo.getId(), destVolumeInfo.getDataStore());
            DataTO dataTO = destVolumeInfo.getTO();
            copyCmdAnswer = new CopyCmdAnswer(dataTO);
        }
        CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
        result.setResult(errMsg);
        callback.complete(result);
    }
}
Also used : HypervisorType(com.cloud.hypervisor.Hypervisor.HypervisorType) DataTO(com.cloud.agent.api.to.DataTO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VMTemplateStoragePoolVO(com.cloud.storage.VMTemplateStoragePoolVO) StoragePoolVO(org.apache.cloudstack.storage.datastore.db.StoragePoolVO) CopyCommandResult(org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult) HostVO(com.cloud.host.HostVO) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) OperationTimedoutException(com.cloud.exception.OperationTimedoutException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer) VirtualMachine(com.cloud.vm.VirtualMachine)

Example 23 with StoragePoolVO

use of org.apache.cloudstack.storage.datastore.db.StoragePoolVO in project cloudstack by apache.

the class VolumeOrchestrator method backupSnapshotIfNeeded.

private SnapshotInfo backupSnapshotIfNeeded(Snapshot snapshot, DataStoreRole dataStoreRole, SnapshotInfo snapInfo) {
    boolean backupSnapToSecondary = SnapshotManager.BackupSnapshotAfterTakingSnapshot.value() == null || SnapshotManager.BackupSnapshotAfterTakingSnapshot.value();
    StoragePoolVO srcPool = _storagePoolDao.findById(snapInfo.getBaseVolume().getPoolId());
    // KVMStorageProcessor::createVolumeFromSnapshot and CloudStackPrimaryDataStoreDriverImpl::copyAsync/createAsync
    if ((!backupSnapToSecondary && (StoragePoolType.NetworkFilesystem.equals(srcPool.getPoolType()) || StoragePoolType.Filesystem.equals(srcPool.getPoolType())))) {
        SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.BACKUP);
        snapshotStrategy.backupSnapshot(snapInfo);
        // Attempt to grab it again.
        snapInfo = snapshotFactory.getSnapshot(snapshot.getId(), dataStoreRole);
        if (snapInfo == null) {
            throw new CloudRuntimeException("Cannot find snapshot " + snapshot.getId() + " on secondary and could not create backup");
        }
    }
    return snapInfo;
}
Also used : CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) StoragePoolVO(org.apache.cloudstack.storage.datastore.db.StoragePoolVO) SnapshotStrategy(org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy)

Example 24 with StoragePoolVO

use of org.apache.cloudstack.storage.datastore.db.StoragePoolVO in project cloudstack by apache.

the class VolumeOrchestrator method updateVolumeDiskChain.

@Override
public void updateVolumeDiskChain(long volumeId, String path, String chainInfo, String updatedDataStoreUUID) {
    VolumeVO vol = _volsDao.findById(volumeId);
    boolean needUpdate = false;
    // Volume path is not getting updated in the DB, need to find reason and fix the issue.
    if (vol.getPath() == null) {
        return;
    }
    if (!vol.getPath().equalsIgnoreCase(path)) {
        needUpdate = true;
    }
    if (chainInfo != null && (vol.getChainInfo() == null || !chainInfo.equalsIgnoreCase(vol.getChainInfo()))) {
        needUpdate = true;
    }
    if (updatedDataStoreUUID != null) {
        needUpdate = true;
    }
    if (needUpdate) {
        s_logger.info("Update volume disk chain info. vol: " + vol.getId() + ", " + vol.getPath() + " -> " + path + ", " + vol.getChainInfo() + " -> " + chainInfo);
        vol.setPath(path);
        vol.setChainInfo(chainInfo);
        if (updatedDataStoreUUID != null) {
            StoragePoolVO pool = _storagePoolDao.findByUuid(updatedDataStoreUUID);
            if (pool != null) {
                vol.setPoolId(pool.getId());
            }
        }
        _volsDao.update(volumeId, vol);
    }
}
Also used : VolumeVO(com.cloud.storage.VolumeVO) StoragePoolVO(org.apache.cloudstack.storage.datastore.db.StoragePoolVO)

Example 25 with StoragePoolVO

use of org.apache.cloudstack.storage.datastore.db.StoragePoolVO in project cloudstack by apache.

the class VolumeOrchestrator method recreateVolume.

private Pair<VolumeVO, DataStore> recreateVolume(VolumeVO vol, VirtualMachineProfile vm, DeployDestination dest) throws StorageUnavailableException, StorageAccessException {
    VolumeVO newVol;
    boolean recreate = RecreatableSystemVmEnabled.value();
    DataStore destPool = null;
    if (recreate && (dest.getStorageForDisks() == null || dest.getStorageForDisks().get(vol) == null)) {
        destPool = dataStoreMgr.getDataStore(vol.getPoolId(), DataStoreRole.Primary);
        s_logger.debug("existing pool: " + destPool.getId());
    } else {
        StoragePool pool = dest.getStorageForDisks().get(vol);
        destPool = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
    }
    if (vol.getState() == Volume.State.Allocated || vol.getState() == Volume.State.Creating) {
        newVol = vol;
    } else {
        newVol = switchVolume(vol, vm);
        // changed
        if (dest.getStorageForDisks() != null && dest.getStorageForDisks().containsKey(vol)) {
            StoragePool poolWithOldVol = dest.getStorageForDisks().get(vol);
            dest.getStorageForDisks().put(newVol, poolWithOldVol);
            dest.getStorageForDisks().remove(vol);
        }
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Created new volume " + newVol + " for old volume " + vol);
        }
    }
    VolumeInfo volume = volFactory.getVolume(newVol.getId(), destPool);
    Long templateId = newVol.getTemplateId();
    for (int i = 0; i < 2; i++) {
        // retry one more time in case of template reload is required for VMware case
        AsyncCallFuture<VolumeApiResult> future;
        if (templateId == null) {
            DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
            HypervisorType hyperType = vm.getVirtualMachine().getHypervisorType();
            // update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
            volService.updateHypervisorSnapshotReserveForVolume(diskOffering, volume.getId(), hyperType);
            volume = volFactory.getVolume(newVol.getId(), destPool);
            future = volService.createVolumeAsync(volume, destPool);
        } else {
            TemplateInfo templ = tmplFactory.getReadyTemplateOnImageStore(templateId, dest.getDataCenter().getId());
            PrimaryDataStore primaryDataStore = (PrimaryDataStore) destPool;
            if (templ == null) {
                if (tmplFactory.isTemplateMarkedForDirectDownload(templateId)) {
                    // Template is marked for direct download bypassing Secondary Storage
                    if (!primaryDataStore.isManaged()) {
                        templ = tmplFactory.getReadyBypassedTemplateOnPrimaryStore(templateId, destPool.getId(), dest.getHost().getId());
                    } else {
                        s_logger.debug("Direct download template: " + templateId + " on host: " + dest.getHost().getId() + " and copy to the managed storage pool: " + destPool.getId());
                        templ = volService.createManagedStorageTemplate(templateId, destPool.getId(), dest.getHost().getId());
                    }
                    if (templ == null) {
                        s_logger.debug("Failed to spool direct download template: " + templateId + " for data center " + dest.getDataCenter().getId());
                        throw new CloudRuntimeException("Failed to spool direct download template: " + templateId + " for data center " + dest.getDataCenter().getId());
                    }
                } else {
                    s_logger.debug("can't find ready template: " + templateId + " for data center " + dest.getDataCenter().getId());
                    throw new CloudRuntimeException("can't find ready template: " + templateId + " for data center " + dest.getDataCenter().getId());
                }
            }
            if (primaryDataStore.isManaged()) {
                DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
                HypervisorType hyperType = vm.getVirtualMachine().getHypervisorType();
                // update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
                volService.updateHypervisorSnapshotReserveForVolume(diskOffering, volume.getId(), hyperType);
                long hostId = vm.getVirtualMachine().getHostId();
                future = volService.createManagedStorageVolumeFromTemplateAsync(volume, destPool.getId(), templ, hostId);
            } else {
                future = volService.createVolumeFromTemplateAsync(volume, destPool.getId(), templ);
            }
        }
        VolumeApiResult result;
        try {
            result = future.get();
            if (result.isFailed()) {
                if (result.getResult().contains(REQUEST_TEMPLATE_RELOAD) && (i == 0)) {
                    s_logger.debug("Retry template re-deploy for vmware");
                    continue;
                } else {
                    s_logger.debug("Unable to create " + newVol + ":" + result.getResult());
                    throw new StorageUnavailableException("Unable to create " + newVol + ":" + result.getResult(), destPool.getId());
                }
            }
            StoragePoolVO storagePool = _storagePoolDao.findById(destPool.getId());
            if (storagePool.isManaged()) {
                long hostId = vm.getVirtualMachine().getHostId();
                Host host = _hostDao.findById(hostId);
                try {
                    volService.grantAccess(volFactory.getVolume(newVol.getId()), host, destPool);
                } catch (Exception e) {
                    throw new StorageAccessException("Unable to grant access to volume: " + newVol.getId() + " on host: " + host.getId());
                }
            }
            newVol = _volsDao.findById(newVol.getId());
            // break out of template-redeploy retry loop
            break;
        } catch (StorageAccessException e) {
            throw e;
        } catch (InterruptedException | ExecutionException e) {
            s_logger.error("Unable to create " + newVol, e);
            throw new StorageUnavailableException("Unable to create " + newVol + ":" + e.toString(), destPool.getId());
        }
    }
    return new Pair<VolumeVO, DataStore>(newVol, destPool);
}
Also used : StoragePool(com.cloud.storage.StoragePool) DiskOffering(com.cloud.offering.DiskOffering) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) Host(com.cloud.host.Host) StorageAccessException(com.cloud.exception.StorageAccessException) VolumeApiResult(org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) InsufficientStorageCapacityException(com.cloud.exception.InsufficientStorageCapacityException) StorageUnavailableException(com.cloud.exception.StorageUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) StorageAccessException(com.cloud.exception.StorageAccessException) ExecutionException(java.util.concurrent.ExecutionException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) ConfigurationException(javax.naming.ConfigurationException) HypervisorType(com.cloud.hypervisor.Hypervisor.HypervisorType) TemplateInfo(org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo) VolumeVO(com.cloud.storage.VolumeVO) StorageUnavailableException(com.cloud.exception.StorageUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) PrimaryDataStore(org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore) DataStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore) StoragePoolVO(org.apache.cloudstack.storage.datastore.db.StoragePoolVO) ExecutionException(java.util.concurrent.ExecutionException) PrimaryDataStore(org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore) Pair(com.cloud.utils.Pair)

Aggregations

StoragePoolVO (org.apache.cloudstack.storage.datastore.db.StoragePoolVO)276 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)106 VMTemplateStoragePoolVO (com.cloud.storage.VMTemplateStoragePoolVO)75 ArrayList (java.util.ArrayList)54 VolumeVO (com.cloud.storage.VolumeVO)53 HostVO (com.cloud.host.HostVO)46 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)45 DataStore (org.apache.cloudstack.engine.subsystem.api.storage.DataStore)45 HashMap (java.util.HashMap)44 Answer (com.cloud.agent.api.Answer)38 VolumeInfo (org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo)35 StoragePool (com.cloud.storage.StoragePool)33 Test (org.junit.Test)33 VMInstanceVO (com.cloud.vm.VMInstanceVO)25 Map (java.util.Map)25 Account (com.cloud.user.Account)24 HypervisorType (com.cloud.hypervisor.Hypervisor.HypervisorType)20 ExecutionException (java.util.concurrent.ExecutionException)20 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)19 ClusterVO (com.cloud.dc.ClusterVO)18