Search in sources :

Example 16 with CreateCmdResult

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

the class SolidFirePrimaryDataStoreDriver method takeSnapshot.

@Override
public void takeSnapshot(SnapshotInfo snapshotInfo, AsyncCompletionCallback<CreateCmdResult> callback) {
    CreateCmdResult result = null;
    try {
        VolumeInfo volumeInfo = snapshotInfo.getBaseVolume();
        VolumeVO volumeVO = volumeDao.findById(volumeInfo.getId());
        long sfVolumeId = Long.parseLong(volumeVO.getFolder());
        long storagePoolId = volumeVO.getPoolId();
        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
        SolidFireUtil.SolidFireVolume sfVolume = SolidFireUtil.getVolume(sfConnection, sfVolumeId);
        StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
        long capacityBytes = storagePool.getCapacityBytes();
        // getUsedBytes(StoragePool) will not include the bytes of the proposed new volume or snapshot because
        // updateSnapshotDetails has not yet been called for this new volume or snapshot
        long usedBytes = getUsedBytes(storagePool);
        long sfVolumeSize = sfVolume.getTotalSize();
        usedBytes += sfVolumeSize;
        // that is serving as the volume the snapshot is of (either a new SolidFire volume or a SolidFire snapshot).
        if (usedBytes > capacityBytes) {
            throw new CloudRuntimeException("Insufficient amount of space remains in this primary storage to take a snapshot");
        }
        storagePool.setUsedBytes(usedBytes);
        SnapshotObjectTO snapshotObjectTo = (SnapshotObjectTO) snapshotInfo.getTO();
        if (shouldTakeSnapshot(snapshotInfo.getId())) {
            // We are supposed to take a SolidFire snapshot to serve as the back-end for our CloudStack volume snapshot.
            String sfNewSnapshotName = volumeInfo.getName() + "-" + snapshotInfo.getUuid();
            long sfNewSnapshotId = SolidFireUtil.createSnapshot(sfConnection, sfVolumeId, sfNewSnapshotName, getSnapshotAttributes(snapshotInfo));
            updateSnapshotDetails(snapshotInfo.getId(), sfVolumeId, sfNewSnapshotId, storagePoolId, sfVolumeSize);
            snapshotObjectTo.setPath("SfSnapshotId=" + sfNewSnapshotId);
        } else {
            // We are supposed to create a new SolidFire volume to serve as the back-end for our CloudStack volume snapshot.
            String sfNewVolumeName = volumeInfo.getName() + "-" + snapshotInfo.getUuid();
            final Iops iops = getIops(MIN_IOPS_FOR_SNAPSHOT_VOLUME, MAX_IOPS_FOR_SNAPSHOT_VOLUME, storagePoolId);
            long sfNewVolumeId = SolidFireUtil.createVolume(sfConnection, sfNewVolumeName, sfVolume.getAccountId(), sfVolumeSize, sfVolume.isEnable512e(), getSnapshotAttributes(snapshotInfo), iops.getMinIops(), iops.getMaxIops(), iops.getBurstIops());
            SolidFireUtil.SolidFireVolume sfNewVolume = SolidFireUtil.getVolume(sfConnection, sfNewVolumeId);
            updateSnapshotDetails(snapshotInfo.getId(), sfNewVolumeId, storagePoolId, sfVolumeSize, sfNewVolume.getIqn());
            snapshotObjectTo.setPath("SfVolumeId=" + sfNewVolumeId);
        }
        // Now that we have successfully created a volume or a snapshot, update the space usage in the cloud.storage_pool table
        // (even though cloud.storage_pool.used_bytes is likely no longer in use).
        storagePoolDao.update(storagePoolId, storagePool);
        CreateObjectAnswer createObjectAnswer = new CreateObjectAnswer(snapshotObjectTo);
        result = new CreateCmdResult(null, createObjectAnswer);
        result.setResult(null);
    } catch (Exception ex) {
        LOGGER.debug(SolidFireUtil.LOG_PREFIX + "Failed to take CloudStack snapshot: " + snapshotInfo.getId(), ex);
        result = new CreateCmdResult(null, new CreateObjectAnswer(ex.toString()));
        result.setResult(ex.toString());
    }
    callback.complete(result);
}
Also used : SnapshotObjectTO(org.apache.cloudstack.storage.to.SnapshotObjectTO) CreateObjectAnswer(org.apache.cloudstack.storage.command.CreateObjectAnswer) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) CreateCmdResult(org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VolumeVO(com.cloud.storage.VolumeVO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VMTemplateStoragePoolVO(com.cloud.storage.VMTemplateStoragePoolVO) StoragePoolVO(org.apache.cloudstack.storage.datastore.db.StoragePoolVO) SolidFireUtil(org.apache.cloudstack.storage.datastore.util.SolidFireUtil)

Example 17 with CreateCmdResult

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

the class NexentaPrimaryDataStoreDriver method createAsync.

@Override
public void createAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback<CreateCmdResult> callback) {
    String iqn = null;
    String errorMessage = null;
    if (dataObject.getType() != DataObjectType.VOLUME) {
        errorMessage = "Invalid DataObjectType (" + dataObject.getType() + ") passed to createAsync";
    } else {
        VolumeInfo volumeInfo = (VolumeInfo) dataObject;
        long storagePoolId = dataStore.getId();
        NexentaStorAppliance appliance = getNexentaStorAppliance(storagePoolId);
        // TODO: maybe we should use md5(volume name) as volume name
        NexentaStorZvol zvol = (NexentaStorZvol) appliance.createVolume(volumeInfo.getName(), volumeInfo.getSize());
        iqn = zvol.getIqn();
        VolumeVO volume = this._volumeDao.findById(volumeInfo.getId());
        volume.set_iScsiName(iqn);
        volume.setFolder(zvol.getName());
        volume.setPoolType(Storage.StoragePoolType.IscsiLUN);
        volume.setPoolId(storagePoolId);
        _volumeDao.update(volume.getId(), volume);
        StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);
        long capacityBytes = storagePool.getCapacityBytes();
        long usedBytes = storagePool.getUsedBytes();
        usedBytes += volumeInfo.getSize();
        storagePool.setUsedBytes(usedBytes > capacityBytes ? capacityBytes : usedBytes);
        _storagePoolDao.update(storagePoolId, storagePool);
    }
    CreateCmdResult result = new CreateCmdResult(iqn, new Answer(null, errorMessage == null, errorMessage));
    result.setResult(errorMessage);
    callback.complete(result);
}
Also used : NexentaStorZvol(org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.NexentaStorZvol) Answer(com.cloud.agent.api.Answer) VolumeVO(com.cloud.storage.VolumeVO) NexentaStorAppliance(org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance) StoragePoolVO(org.apache.cloudstack.storage.datastore.db.StoragePoolVO) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) CreateCmdResult(org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult)

Example 18 with CreateCmdResult

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

the class SolidFirePrimaryDataStoreDriver method resize.

@Override
public void resize(DataObject dataObject, AsyncCompletionCallback<CreateCmdResult> callback) {
    String iqn = null;
    String errMsg = null;
    if (dataObject.getType() == DataObjectType.VOLUME) {
        VolumeInfo volumeInfo = (VolumeInfo) dataObject;
        iqn = volumeInfo.get_iScsiName();
        long storagePoolId = volumeInfo.getPoolId();
        long sfVolumeId = Long.parseLong(volumeInfo.getFolder());
        ResizeVolumePayload payload = (ResizeVolumePayload) volumeInfo.getpayload();
        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
        SolidFireUtil.SolidFireVolume sfVolume = SolidFireUtil.getVolume(sfConnection, sfVolumeId);
        verifySufficientIopsForStoragePool(storagePoolId, volumeInfo.getId(), payload.newMinIops);
        verifySufficientBytesForStoragePool(storagePoolId, volumeInfo.getId(), payload.newSize, payload.newHypervisorSnapshotReserve);
        long sfNewVolumeSize = sfVolume.getTotalSize();
        Integer hsr = volumeInfo.getHypervisorSnapshotReserve();
        if (payload.newSize != null || payload.newHypervisorSnapshotReserve != null) {
            if (payload.newHypervisorSnapshotReserve != null) {
                if (hsr != null) {
                    if (payload.newHypervisorSnapshotReserve > hsr) {
                        hsr = payload.newHypervisorSnapshotReserve;
                    }
                } else {
                    hsr = payload.newHypervisorSnapshotReserve;
                }
            }
            sfNewVolumeSize = getVolumeSizeIncludingHypervisorSnapshotReserve(payload.newSize, hsr);
        }
        Map<String, String> mapAttributes = new HashMap<>();
        mapAttributes.put(SolidFireUtil.CloudStackVolumeId, String.valueOf(volumeInfo.getId()));
        mapAttributes.put(SolidFireUtil.CloudStackVolumeSize, NumberFormat.getInstance().format(payload.newSize));
        SolidFireUtil.modifyVolume(sfConnection, sfVolumeId, sfNewVolumeSize, mapAttributes, payload.newMinIops, payload.newMaxIops, getDefaultBurstIops(storagePoolId, payload.newMaxIops));
        VolumeVO volume = volumeDao.findById(volumeInfo.getId());
        volume.setMinIops(payload.newMinIops);
        volume.setMaxIops(payload.newMaxIops);
        volume.setHypervisorSnapshotReserve(hsr);
        volumeDao.update(volume.getId(), volume);
        // SolidFireUtil.VOLUME_SIZE was introduced in 4.5.
        updateVolumeDetails(volume.getId(), sfNewVolumeSize);
    } else {
        errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to resize";
    }
    CreateCmdResult result = new CreateCmdResult(iqn, new Answer(null, errMsg == null, errMsg));
    result.setResult(errMsg);
    callback.complete(result);
}
Also used : HashMap(java.util.HashMap) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) CreateCmdResult(org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult) CreateObjectAnswer(org.apache.cloudstack.storage.command.CreateObjectAnswer) Answer(com.cloud.agent.api.Answer) VolumeVO(com.cloud.storage.VolumeVO) ResizeVolumePayload(com.cloud.storage.ResizeVolumePayload) SolidFireUtil(org.apache.cloudstack.storage.datastore.util.SolidFireUtil)

Example 19 with CreateCmdResult

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

the class VolumeServiceImpl method createVolumeCallback.

protected Void createVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
    CreateCmdResult result = callback.getResult();
    DataObject vo = context.getVolume();
    String errMsg = null;
    if (result.isSuccess()) {
        vo.processEvent(Event.OperationSuccessed, result.getAnswer());
    } else {
        vo.processEvent(Event.OperationFailed);
        errMsg = result.getResult();
    }
    VolumeApiResult volResult = new VolumeApiResult((VolumeObject) vo);
    if (errMsg != null) {
        volResult.setResult(errMsg);
    }
    context.getFuture().complete(volResult);
    return null;
}
Also used : DataObject(org.apache.cloudstack.engine.subsystem.api.storage.DataObject) CreateCmdResult(org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult)

Example 20 with CreateCmdResult

use of org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult 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)

Aggregations

CreateCmdResult (org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult)38 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)24 DataObject (org.apache.cloudstack.engine.subsystem.api.storage.DataObject)12 NoTransitionException (com.cloud.utils.fsm.NoTransitionException)10 VolumeInfo (org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo)9 Answer (com.cloud.agent.api.Answer)8 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)8 CopyCommandResult (org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult)7 AsyncCallFuture (org.apache.cloudstack.framework.async.AsyncCallFuture)7 ResourceAllocationException (com.cloud.exception.ResourceAllocationException)6 VolumeVO (com.cloud.storage.VolumeVO)6 EndPoint (org.apache.cloudstack.engine.subsystem.api.storage.EndPoint)6 TemplateInfo (org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo)6 CreateObjectAnswer (org.apache.cloudstack.storage.command.CreateObjectAnswer)6 DownloadAnswer (com.cloud.agent.api.storage.DownloadAnswer)5 DataStore (org.apache.cloudstack.engine.subsystem.api.storage.DataStore)4 StoragePoolVO (org.apache.cloudstack.storage.datastore.db.StoragePoolVO)4 ResizeVolumeAnswer (com.cloud.agent.api.storage.ResizeVolumeAnswer)3 StorageUnavailableException (com.cloud.exception.StorageUnavailableException)3 ResizeVolumePayload (com.cloud.storage.ResizeVolumePayload)3