Search in sources :

Example 21 with CopyCommandResult

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

the class VolumeServiceImpl method copyBaseImageCallback.

@DB
protected Void copyBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CreateBaseImageContext<VolumeApiResult> context) {
    CopyCommandResult result = callback.getResult();
    VolumeApiResult res = new VolumeApiResult(context.getVolume());
    AsyncCallFuture<VolumeApiResult> future = context.getFuture();
    DataObject templateOnPrimaryStoreObj = context.destObj;
    if (!result.isSuccess()) {
        templateOnPrimaryStoreObj.processEvent(Event.OperationFailed);
        res.setResult(result.getResult());
        future.complete(res);
        return null;
    }
    templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed, result.getAnswer());
    createVolumeFromBaseImageAsync(context.volume, templateOnPrimaryStoreObj, context.dataStore, future);
    return null;
}
Also used : DataObject(org.apache.cloudstack.engine.subsystem.api.storage.DataObject) CopyCommandResult(org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult) DB(com.cloud.utils.db.DB)

Example 22 with CopyCommandResult

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

the class VolumeServiceImpl method createBaseImageAsync.

@DB
protected void createBaseImageAsync(VolumeInfo volume, PrimaryDataStore dataStore, TemplateInfo template, AsyncCallFuture<VolumeApiResult> future) {
    DataObject templateOnPrimaryStoreObj = dataStore.create(template);
    VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(dataStore.getId(), template.getId());
    if (templatePoolRef == null) {
        throw new CloudRuntimeException("Failed to find template " + template.getUniqueName() + " in storage pool " + dataStore.getId());
    } else {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Found template " + template.getUniqueName() + " in storage pool " + dataStore.getId() + " with VMTemplateStoragePool id: " + templatePoolRef.getId());
        }
    }
    long templatePoolRefId = templatePoolRef.getId();
    CreateBaseImageContext<CreateCmdResult> context = new CreateBaseImageContext<CreateCmdResult>(null, volume, dataStore, template, future, templateOnPrimaryStoreObj, templatePoolRefId);
    AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
    caller.setCallback(caller.getTarget().copyBaseImageCallback(null, null)).setContext(context);
    int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
    if (s_logger.isDebugEnabled()) {
        s_logger.debug("Acquire lock on VMTemplateStoragePool " + templatePoolRefId + " with timeout " + storagePoolMaxWaitSeconds + " seconds");
    }
    templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolRefId, storagePoolMaxWaitSeconds);
    if (templatePoolRef == null) {
        if (s_logger.isDebugEnabled()) {
            s_logger.info("Unable to acquire lock on VMTemplateStoragePool " + templatePoolRefId);
        }
        templatePoolRef = _tmpltPoolDao.findByPoolTemplate(dataStore.getId(), template.getId());
        if (templatePoolRef != null && templatePoolRef.getState() == ObjectInDataStoreStateMachine.State.Ready) {
            s_logger.info("Unable to acquire lock on VMTemplateStoragePool " + templatePoolRefId + ", But Template " + template.getUniqueName() + " is already copied to primary storage, skip copying");
            createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, dataStore, future);
            return;
        }
        throw new CloudRuntimeException("Unable to acquire lock on VMTemplateStoragePool: " + templatePoolRefId);
    }
    if (s_logger.isDebugEnabled()) {
        s_logger.info("lock is acquired for VMTemplateStoragePool " + templatePoolRefId);
    }
    try {
        if (templatePoolRef.getState() == ObjectInDataStoreStateMachine.State.Ready) {
            s_logger.info("Template " + template.getUniqueName() + " is already copied to primary storage, skip copying");
            createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, dataStore, future);
            return;
        }
        templateOnPrimaryStoreObj.processEvent(Event.CreateOnlyRequested);
        motionSrv.copyAsync(template, templateOnPrimaryStoreObj, caller);
    } catch (Throwable e) {
        s_logger.debug("failed to create template on storage", e);
        templateOnPrimaryStoreObj.processEvent(Event.OperationFailed);
        // make sure that template_spool_ref entry is still present so that the second thread can acquire the lock
        dataStore.create(template);
        VolumeApiResult result = new VolumeApiResult(volume);
        result.setResult(e.toString());
        future.complete(result);
    } finally {
        if (s_logger.isDebugEnabled()) {
            s_logger.info("releasing lock for VMTemplateStoragePool " + templatePoolRefId);
        }
        _tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
    }
    return;
}
Also used : CreateCmdResult(org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult) EndPoint(org.apache.cloudstack.engine.subsystem.api.storage.EndPoint) RemoteHostEndPoint(org.apache.cloudstack.storage.RemoteHostEndPoint) VMTemplateStoragePoolVO(com.cloud.storage.VMTemplateStoragePoolVO) DataObject(org.apache.cloudstack.engine.subsystem.api.storage.DataObject) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) CopyCommandResult(org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult) DB(com.cloud.utils.db.DB)

Example 23 with CopyCommandResult

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

the class VolumeServiceImpl method migrateVolumes.

@Override
public AsyncCallFuture<CommandResult> migrateVolumes(Map<VolumeInfo, DataStore> volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost) {
    AsyncCallFuture<CommandResult> future = new AsyncCallFuture<CommandResult>();
    CommandResult res = new CommandResult();
    try {
        // Check to make sure there are no snapshot operations on a volume
        // and
        // put it in the migrating state.
        List<VolumeInfo> volumesMigrating = new ArrayList<VolumeInfo>();
        for (Map.Entry<VolumeInfo, DataStore> entry : volumeMap.entrySet()) {
            VolumeInfo volume = entry.getKey();
            if (!snapshotMgr.canOperateOnVolume(volume)) {
                s_logger.debug("Snapshots are being created on a volume. Volumes cannot be migrated now.");
                res.setResult("Snapshots are being created on a volume. Volumes cannot be migrated now.");
                future.complete(res);
                // to be put back in ready state.
                for (VolumeInfo volumeMigrating : volumesMigrating) {
                    volumeMigrating.processEvent(Event.OperationFailed);
                }
                return future;
            } else {
                volume.processEvent(Event.MigrationRequested);
                volumesMigrating.add(volume);
            }
        }
        MigrateVmWithVolumesContext<CommandResult> context = new MigrateVmWithVolumesContext<CommandResult>(null, future, volumeMap);
        AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
        caller.setCallback(caller.getTarget().migrateVmWithVolumesCallBack(null, null)).setContext(context);
        motionSrv.copyAsync(volumeMap, vmTo, srcHost, destHost, caller);
    } catch (Exception e) {
        s_logger.debug("Failed to copy volume", e);
        res.setResult(e.toString());
        future.complete(res);
    }
    return future;
}
Also used : ArrayList(java.util.ArrayList) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) CommandResult(org.apache.cloudstack.storage.command.CommandResult) CopyCommandResult(org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult) AsyncCallFuture(org.apache.cloudstack.framework.async.AsyncCallFuture) DataStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore) PrimaryDataStore(org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore) Map(java.util.Map) HashMap(java.util.HashMap) CopyCommandResult(org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult)

Example 24 with CopyCommandResult

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

the class VolumeServiceImpl method copyVolumeFromImageToPrimary.

protected AsyncCallFuture<VolumeApiResult> copyVolumeFromImageToPrimary(VolumeInfo srcVolume, DataStore destStore) {
    AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
    VolumeApiResult res = new VolumeApiResult(srcVolume);
    VolumeInfo destVolume = null;
    try {
        destVolume = (VolumeInfo) destStore.create(srcVolume);
        destVolume.processEvent(Event.CopyingRequested);
        srcVolume.processEvent(Event.CopyingRequested);
        CopyVolumeContext<VolumeApiResult> context = new CopyVolumeContext<VolumeApiResult>(null, future, srcVolume, destVolume, destStore);
        AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
        caller.setCallback(caller.getTarget().copyVolumeFromImageToPrimaryCallback(null, null)).setContext(context);
        motionSrv.copyAsync(srcVolume, destVolume, caller);
        return future;
    } catch (Exception e) {
        s_logger.error("failed to copy volume from image store", e);
        if (destVolume != null) {
            destVolume.processEvent(Event.OperationFailed);
        }
        srcVolume.processEvent(Event.OperationFailed);
        res.setResult(e.toString());
        future.complete(res);
        return future;
    }
}
Also used : AsyncCallFuture(org.apache.cloudstack.framework.async.AsyncCallFuture) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) CopyCommandResult(org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException)

Example 25 with CopyCommandResult

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

the class VolumeServiceImpl method copyTemplateToManagedTemplateVolume.

/**
     * This function copies a template from secondary storage to a template volume
     * created on managed storage. This template volume will be used as a cache.
     * Instead of copying the template to a ROOT volume every time, a clone is performed instead.
     *
     * @param srcTemplateInfo Source from which to copy the template
     * @param templateOnPrimary Dest to copy to
     * @param templatePoolRef Template reference on primary storage (entry in the template_spool_ref)
     * @param destPrimaryDataStore The managed primary storage
     * @param destHost The host that we will use for the copy
     */
private void copyTemplateToManagedTemplateVolume(TemplateInfo srcTemplateInfo, TemplateInfo templateOnPrimary, VMTemplateStoragePoolVO templatePoolRef, PrimaryDataStore destPrimaryDataStore, Host destHost) {
    AsyncCallFuture<VolumeApiResult> copyTemplateFuture = new AsyncCallFuture<>();
    int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
    long templatePoolRefId = templatePoolRef.getId();
    templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolRefId, storagePoolMaxWaitSeconds);
    if (templatePoolRef == null) {
        throw new CloudRuntimeException("Unable to acquire lock on VMTemplateStoragePool: " + templatePoolRefId);
    }
    if (templatePoolRef.getDownloadState() == Status.DOWNLOADED) {
        // There can be cases where we acquired the lock, but the template
        // was already copied by a previous thread. Just return in that case.
        s_logger.debug("Template already downloaded, nothing to do");
        return;
    }
    try {
        // copy the template from sec storage to the created volume
        CreateBaseImageContext<CreateCmdResult> copyContext = new CreateBaseImageContext<>(null, null, destPrimaryDataStore, srcTemplateInfo, copyTemplateFuture, templateOnPrimary, templatePoolRefId);
        AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> copyCaller = AsyncCallbackDispatcher.create(this);
        copyCaller.setCallback(copyCaller.getTarget().copyManagedTemplateCallback(null, null)).setContext(copyContext);
        // Populate details which will be later read by the storage subsystem.
        Map<String, String> details = new HashMap<String, String>();
        details.put(PrimaryDataStore.MANAGED, Boolean.TRUE.toString());
        details.put(PrimaryDataStore.STORAGE_HOST, destPrimaryDataStore.getHostAddress());
        details.put(PrimaryDataStore.STORAGE_PORT, String.valueOf(destPrimaryDataStore.getPort()));
        details.put(PrimaryDataStore.MANAGED_STORE_TARGET, ((TemplateObject) templateOnPrimary).getInstallPath());
        details.put(PrimaryDataStore.MANAGED_STORE_TARGET_ROOT_VOLUME, srcTemplateInfo.getUniqueName());
        details.put(PrimaryDataStore.REMOVE_AFTER_COPY, Boolean.TRUE.toString());
        details.put(PrimaryDataStore.VOLUME_SIZE, String.valueOf(templateOnPrimary.getSize()));
        ChapInfo chapInfo = getChapInfo(templateOnPrimary, destPrimaryDataStore);
        if (chapInfo != null) {
            details.put(PrimaryDataStore.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername());
            details.put(PrimaryDataStore.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret());
            details.put(PrimaryDataStore.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
            details.put(PrimaryDataStore.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
        }
        templateOnPrimary.processEvent(Event.CopyingRequested);
        destPrimaryDataStore.setDetails(details);
        grantAccess(templateOnPrimary, destHost, destPrimaryDataStore);
        VolumeApiResult result = null;
        try {
            motionSrv.copyAsync(srcTemplateInfo, templateOnPrimary, destHost, copyCaller);
            result = copyTemplateFuture.get();
        } finally {
            revokeAccess(templateOnPrimary, destHost, destPrimaryDataStore);
        }
        if (result.isFailed()) {
            throw new CloudRuntimeException("Failed to copy template " + templateOnPrimary.getId() + " to primary storage " + destPrimaryDataStore.getId() + ": " + result.getResult());
        // XXX: I find it is useful to destroy the volume on primary storage instead of another thread trying the copy again because I've seen
        // something weird happens to the volume (XenServer creates an SR, but the VDI copy can fail).
        // For now, I just retry the copy.
        }
    } catch (Throwable e) {
        s_logger.debug("Failed to create a template on primary storage", e);
        templateOnPrimary.processEvent(Event.OperationFailed);
        throw new CloudRuntimeException(e.getMessage());
    } finally {
        _tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
    }
}
Also used : HashMap(java.util.HashMap) ChapInfo(org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo) CreateCmdResult(org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult) EndPoint(org.apache.cloudstack.engine.subsystem.api.storage.EndPoint) RemoteHostEndPoint(org.apache.cloudstack.storage.RemoteHostEndPoint) AsyncCallFuture(org.apache.cloudstack.framework.async.AsyncCallFuture) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) CopyCommandResult(org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult)

Aggregations

CopyCommandResult (org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult)49 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)32 VolumeInfo (org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo)16 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)15 ResourceAllocationException (com.cloud.exception.ResourceAllocationException)15 AsyncCallFuture (org.apache.cloudstack.framework.async.AsyncCallFuture)13 DataObject (org.apache.cloudstack.engine.subsystem.api.storage.DataObject)11 DataStore (org.apache.cloudstack.engine.subsystem.api.storage.DataStore)9 HashMap (java.util.HashMap)8 ExecutionException (java.util.concurrent.ExecutionException)8 CopyCmdAnswer (org.apache.cloudstack.storage.command.CopyCmdAnswer)8 MigrateWithStorageAnswer (com.cloud.agent.api.MigrateWithStorageAnswer)7 NoTransitionException (com.cloud.utils.fsm.NoTransitionException)7 VMInstanceVO (com.cloud.vm.VMInstanceVO)7 CommandResult (org.apache.cloudstack.storage.command.CommandResult)7 Answer (com.cloud.agent.api.Answer)6 AgentUnavailableException (com.cloud.exception.AgentUnavailableException)6 OperationTimedoutException (com.cloud.exception.OperationTimedoutException)6 CreateCmdResult (org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult)5 EndPoint (org.apache.cloudstack.engine.subsystem.api.storage.EndPoint)5