Search in sources :

Example 1 with DataStore

use of org.apache.cloudstack.engine.subsystem.api.storage.DataStore in project cloudstack by apache.

the class StorageSystemDataMotionStrategy method handleCopyDataToSecondaryStorage.

/**
     * This function is responsible for copying a volume from the managed store to a secondary store. This is used in 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 handleCopyDataToSecondaryStorage(SnapshotInfo snapshotInfo, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
    try {
        snapshotInfo.processEvent(Event.CopyingRequested);
    } catch (Exception ex) {
        throw new CloudRuntimeException("This snapshot is not currently in a state where it can be used to create a template.");
    }
    HostVO hostVO = getHost(snapshotInfo);
    boolean usingBackendSnapshot = usingBackendSnapshotFor(snapshotInfo);
    boolean computeClusterSupportsResign = clusterDao.getSupportsResigning(hostVO.getClusterId());
    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);
    }
    if (usingBackendSnapshot && !computeClusterSupportsResign) {
        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);
    }
    try {
        if (usingBackendSnapshot) {
            createVolumeFromSnapshot(hostVO, snapshotInfo, true);
        }
        DataStore srcDataStore = snapshotInfo.getDataStore();
        String value = _configDao.getValue(Config.PrimaryStorageDownloadWait.toString());
        int primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));
        CopyCommand copyCommand = new CopyCommand(snapshotInfo.getTO(), destOnStore.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value());
        String errMsg = null;
        CopyCmdAnswer copyCmdAnswer = null;
        try {
            // (because we passed in true as the third parameter to createVolumeFromSnapshot above).
            if (!usingBackendSnapshot) {
                _volumeService.grantAccess(snapshotInfo, hostVO, srcDataStore);
            }
            Map<String, String> srcDetails = getSnapshotDetails(snapshotInfo);
            copyCommand.setOptions(srcDetails);
            copyCmdAnswer = (CopyCmdAnswer) _agentMgr.send(hostVO.getId(), copyCommand);
            if (!copyCmdAnswer.getResult()) {
                // We were not able to copy. Handle it.
                errMsg = copyCmdAnswer.getDetails();
                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 cleanup 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());
        } finally {
            _volumeService.revokeAccess(snapshotInfo, hostVO, srcDataStore);
            if (copyCmdAnswer == null || !copyCmdAnswer.getResult()) {
                if (copyCmdAnswer != null && !StringUtils.isEmpty(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);
            }
        }
        CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
        result.setResult(errMsg);
        callback.complete(result);
    } finally {
        if (usingBackendSnapshot) {
            deleteVolumeFromSnapshot(snapshotInfo);
        }
    }
}
Also used : OperationTimedoutException(com.cloud.exception.OperationTimedoutException) CopyCommand(org.apache.cloudstack.storage.command.CopyCommand) EndPoint(org.apache.cloudstack.engine.subsystem.api.storage.EndPoint) TimeoutException(java.util.concurrent.TimeoutException) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) OperationTimedoutException(com.cloud.exception.OperationTimedoutException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) ExecutionException(java.util.concurrent.ExecutionException) HostVO(com.cloud.host.HostVO) EndPoint(org.apache.cloudstack.engine.subsystem.api.storage.EndPoint) DataObject(org.apache.cloudstack.engine.subsystem.api.storage.DataObject) ZoneScope(org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope) Scope(org.apache.cloudstack.engine.subsystem.api.storage.Scope) HostScope(org.apache.cloudstack.engine.subsystem.api.storage.HostScope) ClusterScope(org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) DataStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore) CopyCommandResult(org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer)

Example 2 with DataStore

use of org.apache.cloudstack.engine.subsystem.api.storage.DataStore in project cloudstack by apache.

the class StorageSystemDataMotionStrategy method canStorageSystemCreateVolumeFromVolume.

private boolean canStorageSystemCreateVolumeFromVolume(SnapshotInfo snapshotInfo) {
    boolean supportsCloningVolumeFromVolume = false;
    DataStore dataStore = dataStoreMgr.getDataStore(snapshotInfo.getDataStore().getId(), DataStoreRole.Primary);
    Map<String, String> mapCapabilities = dataStore.getDriver().getCapabilities();
    if (mapCapabilities != null) {
        String value = mapCapabilities.get(DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_VOLUME.toString());
        supportsCloningVolumeFromVolume = Boolean.valueOf(value);
    }
    return supportsCloningVolumeFromVolume;
}
Also used : DataStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore)

Example 3 with DataStore

use of org.apache.cloudstack.engine.subsystem.api.storage.DataStore in project cloudstack by apache.

the class SnapshotManagerImpl method getDataStoreRole.

private static DataStoreRole getDataStoreRole(Snapshot snapshot, SnapshotDataStoreDao snapshotStoreDao, DataStoreManager dataStoreMgr) {
    SnapshotDataStoreVO snapshotStore = snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Primary);
    if (snapshotStore == null) {
        return DataStoreRole.Image;
    }
    long storagePoolId = snapshotStore.getDataStoreId();
    DataStore dataStore = dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
    Map<String, String> mapCapabilities = dataStore.getDriver().getCapabilities();
    if (mapCapabilities != null) {
        String value = mapCapabilities.get(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString());
        Boolean supportsStorageSystemSnapshots = new Boolean(value);
        if (supportsStorageSystemSnapshots) {
            return DataStoreRole.Primary;
        }
    }
    return DataStoreRole.Image;
}
Also used : DataStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore) SnapshotDataStoreVO(org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO)

Example 4 with DataStore

use of org.apache.cloudstack.engine.subsystem.api.storage.DataStore in project cloudstack by apache.

the class XenserverSnapshotStrategy method takeSnapshot.

@Override
@DB
public SnapshotInfo takeSnapshot(SnapshotInfo snapshot) {
    Object payload = snapshot.getPayload();
    if (payload != null) {
        CreateSnapshotPayload createSnapshotPayload = (CreateSnapshotPayload) payload;
        if (createSnapshotPayload.getQuiescevm()) {
            throw new InvalidParameterValueException("can't handle quiescevm equal true for volume snapshot");
        }
    }
    SnapshotVO snapshotVO = snapshotDao.acquireInLockTable(snapshot.getId());
    if (snapshotVO == null) {
        throw new CloudRuntimeException("Failed to get lock on snapshot:" + snapshot.getId());
    }
    try {
        VolumeInfo volumeInfo = snapshot.getBaseVolume();
        volumeInfo.stateTransit(Volume.Event.SnapshotRequested);
        SnapshotResult result = null;
        try {
            result = snapshotSvr.takeSnapshot(snapshot);
            if (result.isFailed()) {
                s_logger.debug("Failed to take snapshot: " + result.getResult());
                throw new CloudRuntimeException(result.getResult());
            }
        } finally {
            if (result != null && result.isSuccess()) {
                volumeInfo.stateTransit(Volume.Event.OperationSucceeded);
            } else {
                volumeInfo.stateTransit(Volume.Event.OperationFailed);
            }
        }
        snapshot = result.getSnapshot();
        DataStore primaryStore = snapshot.getDataStore();
        boolean backupFlag = Boolean.parseBoolean(configDao.getValue(Config.BackupSnapshotAfterTakingSnapshot.toString()));
        SnapshotInfo backupedSnapshot;
        if (backupFlag) {
            backupedSnapshot = backupSnapshot(snapshot);
        } else {
            // Fake it to get the transitions to fire in the proper order
            s_logger.debug("skipping backup of snapshot due to configuration " + Config.BackupSnapshotAfterTakingSnapshot.toString());
            SnapshotObject snapObj = (SnapshotObject) snapshot;
            try {
                snapObj.processEvent(Snapshot.Event.OperationNotPerformed);
            } catch (NoTransitionException e) {
                s_logger.debug("Failed to change state: " + snapshot.getId() + ": " + e.toString());
                throw new CloudRuntimeException(e.toString());
            }
            backupedSnapshot = snapshot;
        }
        try {
            SnapshotInfo parent = snapshot.getParent();
            if (backupedSnapshot != null && parent != null && primaryStore instanceof PrimaryDataStoreImpl) {
                if (((PrimaryDataStoreImpl) primaryStore).getPoolType() != StoragePoolType.RBD) {
                    Long parentSnapshotId = parent.getId();
                    while (parentSnapshotId != null && parentSnapshotId != 0L) {
                        SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(), primaryStore.getId(), parentSnapshotId);
                        if (snapshotDataStoreVO != null) {
                            parentSnapshotId = snapshotDataStoreVO.getParentSnapshotId();
                            snapshotStoreDao.remove(snapshotDataStoreVO.getId());
                        } else {
                            parentSnapshotId = null;
                        }
                    }
                }
                SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(), primaryStore.getId(), snapshot.getId());
                if (snapshotDataStoreVO != null) {
                    snapshotDataStoreVO.setParentSnapshotId(0L);
                    snapshotStoreDao.update(snapshotDataStoreVO.getId(), snapshotDataStoreVO);
                }
            }
        } catch (Exception e) {
            s_logger.debug("Failed to clean up snapshots on primary storage", e);
        }
        return backupedSnapshot;
    } finally {
        if (snapshotVO != null) {
            snapshotDao.releaseFromLockTable(snapshot.getId());
        }
    }
}
Also used : SnapshotResult(org.apache.cloudstack.engine.subsystem.api.storage.SnapshotResult) SnapshotDataStoreVO(org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO) CreateSnapshotPayload(com.cloud.storage.CreateSnapshotPayload) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) SnapshotInfo(org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo) SnapshotVO(com.cloud.storage.SnapshotVO) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) PrimaryDataStoreImpl(org.apache.cloudstack.storage.datastore.PrimaryDataStoreImpl) DataStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) DB(com.cloud.utils.db.DB)

Example 5 with DataStore

use of org.apache.cloudstack.engine.subsystem.api.storage.DataStore in project cloudstack by apache.

the class SnapshotTestWithFakeData method testConcurrentSnapshot.

@Test
public void testConcurrentSnapshot() throws URISyntaxException, InterruptedException, ExecutionException {
    DataStore store = createDataStore();
    final FakePrimaryDataStoreDriver dataStoreDriver = (FakePrimaryDataStoreDriver) store.getDriver();
    dataStoreDriver.makeTakeSnapshotSucceed(true);
    final VolumeInfo volumeInfo = createVolume(1L, store);
    Assert.assertTrue(volumeInfo.getState() == Volume.State.Ready);
    vol = volumeInfo;
    // final SnapshotPolicyVO policyVO = createSnapshotPolicy(vol.getId());
    ExecutorService pool = Executors.newFixedThreadPool(2);
    boolean result = false;
    List<Future<Boolean>> future = new ArrayList<Future<Boolean>>();
    for (int i = 0; i < 12; i++) {
        final int cnt = i;
        Future<Boolean> task = pool.submit(new Callable<Boolean>() {

            @Override
            public Boolean call() throws Exception {
                boolean r = true;
                try {
                    SnapshotVO snapshotVO = createSnapshotInDb(vol.getId());
                    VolumeObject volumeObject = (VolumeObject) vol;
                    Account account = mock(Account.class);
                    when(account.getId()).thenReturn(1L);
                    CreateSnapshotPayload createSnapshotPayload = mock(CreateSnapshotPayload.class);
                    when(createSnapshotPayload.getAccount()).thenReturn(account);
                    when(createSnapshotPayload.getSnapshotId()).thenReturn(snapshotVO.getId());
                    when(createSnapshotPayload.getSnapshotPolicyId()).thenReturn(0L);
                    volumeObject.addPayload(createSnapshotPayload);
                    if (cnt > 8) {
                        mockStorageMotionStrategy.makeBackupSnapshotSucceed(false);
                    }
                    SnapshotInfo newSnapshot = volumeService.takeSnapshot(vol);
                    if (newSnapshot == null) {
                        r = false;
                    }
                } catch (Exception e) {
                    r = false;
                }
                return r;
            }
        });
        Assert.assertTrue(task.get());
    }
}
Also used : Account(com.cloud.user.Account) ArrayList(java.util.ArrayList) CreateSnapshotPayload(com.cloud.storage.CreateSnapshotPayload) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) VolumeObject(org.apache.cloudstack.storage.volume.VolumeObject) URISyntaxException(java.net.URISyntaxException) ExecutionException(java.util.concurrent.ExecutionException) SnapshotInfo(org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo) SnapshotVO(com.cloud.storage.SnapshotVO) DataStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore) ExecutorService(java.util.concurrent.ExecutorService) Future(java.util.concurrent.Future) Test(org.junit.Test)

Aggregations

DataStore (org.apache.cloudstack.engine.subsystem.api.storage.DataStore)221 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)81 VolumeInfo (org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo)71 ExecutionException (java.util.concurrent.ExecutionException)50 StoragePoolVO (org.apache.cloudstack.storage.datastore.db.StoragePoolVO)42 PrimaryDataStore (org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore)38 ArrayList (java.util.ArrayList)37 HashMap (java.util.HashMap)35 VolumeVO (com.cloud.storage.VolumeVO)34 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)30 VMTemplateVO (com.cloud.storage.VMTemplateVO)30 TemplateInfo (org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo)29 HostVO (com.cloud.host.HostVO)26 ZoneScope (org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope)26 EndPoint (org.apache.cloudstack.engine.subsystem.api.storage.EndPoint)25 SnapshotDataStoreVO (org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO)23 TemplateDataStoreVO (org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO)23 AgentUnavailableException (com.cloud.exception.AgentUnavailableException)22 OperationTimedoutException (com.cloud.exception.OperationTimedoutException)22 VolumeApiResult (org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult)22