use of org.apache.cloudstack.engine.subsystem.api.storage.DataObject 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);
}
}
}
use of org.apache.cloudstack.engine.subsystem.api.storage.DataObject in project cloudstack by apache.
the class StorageSystemDataMotionStrategy method cacheSnapshotChain.
protected DataObject cacheSnapshotChain(SnapshotInfo snapshot, Scope scope) {
DataObject leafData = null;
DataStore store = cacheMgr.getCacheStorage(snapshot, scope);
while (snapshot != null) {
DataObject cacheData = cacheMgr.createCacheObject(snapshot, store);
if (leafData == null) {
leafData = cacheData;
}
snapshot = snapshot.getParent();
}
return leafData;
}
use of org.apache.cloudstack.engine.subsystem.api.storage.DataObject in project cloudstack by apache.
the class StorageCacheManagerImpl method getCacheObject.
@Override
public DataObject getCacheObject(DataObject data, Scope scope) {
DataStore cacheStore = getCacheStorage(scope);
DataObject objOnCacheStore = cacheStore.create(data);
objOnCacheStore.incRefCount();
return objOnCacheStore;
}
use of org.apache.cloudstack.engine.subsystem.api.storage.DataObject in project cloudstack by apache.
the class DataObjectManagerImpl method deleteAsynCallback.
protected Void deleteAsynCallback(AsyncCallbackDispatcher<DataObjectManagerImpl, CommandResult> callback, DeleteContext<CommandResult> context) {
DataObject destObj = context.obj;
CommandResult res = callback.getResult();
if (res.isFailed()) {
try {
objectInDataStoreMgr.update(destObj, Event.OperationFailed);
} catch (NoTransitionException e) {
s_logger.debug("delete failed", e);
} catch (ConcurrentOperationException e) {
s_logger.debug("delete failed", e);
}
} else {
try {
objectInDataStoreMgr.update(destObj, Event.OperationSuccessed);
} catch (NoTransitionException e) {
s_logger.debug("delete failed", e);
} catch (ConcurrentOperationException e) {
s_logger.debug("delete failed", e);
}
}
context.getParentCallback().complete(res);
return null;
}
use of org.apache.cloudstack.engine.subsystem.api.storage.DataObject in project cloudstack by apache.
the class BaseImageStoreDriverImpl method createVolumeAsyncCallback.
protected Void createVolumeAsyncCallback(AsyncCallbackDispatcher<? extends BaseImageStoreDriverImpl, DownloadAnswer> callback, CreateContext<CreateCmdResult> context) {
DownloadAnswer answer = callback.getResult();
DataObject obj = context.data;
DataStore store = obj.getDataStore();
VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), obj.getId());
if (volStoreVO != null) {
if (volStoreVO.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Volume is already in DOWNLOADED state, ignore further incoming DownloadAnswer");
}
return null;
}
VolumeDataStoreVO updateBuilder = _volumeStoreDao.createForUpdate();
updateBuilder.setDownloadPercent(answer.getDownloadPct());
updateBuilder.setDownloadState(answer.getDownloadStatus());
updateBuilder.setLastUpdated(new Date());
updateBuilder.setErrorString(answer.getErrorString());
updateBuilder.setJobId(answer.getJobId());
updateBuilder.setLocalDownloadPath(answer.getDownloadPath());
updateBuilder.setInstallPath(answer.getInstallPath());
updateBuilder.setSize(answer.getTemplateSize());
updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize());
_volumeStoreDao.update(volStoreVO.getId(), updateBuilder);
// update size in volume table
VolumeVO volUpdater = volumeDao.createForUpdate();
volUpdater.setSize(answer.getTemplateSize());
volumeDao.update(obj.getId(), volUpdater);
}
AsyncCompletionCallback<CreateCmdResult> caller = context.getParentCallback();
if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) {
CreateCmdResult result = new CreateCmdResult(null, null);
result.setSuccess(false);
result.setResult(answer.getErrorString());
caller.complete(result);
String msg = "Failed to upload volume: " + obj.getUuid() + " with error: " + answer.getErrorString();
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPLOAD_FAILED, (volStoreVO == null ? -1L : volStoreVO.getZoneId()), null, msg, msg);
s_logger.error(msg);
} else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
CreateCmdResult result = new CreateCmdResult(null, null);
caller.complete(result);
}
return null;
}
Aggregations