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);
}
}
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);
}
}
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;
}
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);
}
}
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);
}
Aggregations