use of com.cloud.engine.subsystem.api.storage.VolumeInfo in project cosmic by MissionCriticalCloud.
the class VolumeOrchestrator method createVolumeOnPrimaryStorage.
@Override
public VolumeInfo createVolumeOnPrimaryStorage(final VirtualMachine vm, final VolumeInfo volume, final HypervisorType rootDiskHyperType, final StoragePool storagePool) throws NoTransitionException {
final VirtualMachineTemplate rootDiskTmplt = _entityMgr.findById(VirtualMachineTemplate.class, vm.getTemplateId());
final DataCenter dcVO = _entityMgr.findById(DataCenter.class, vm.getDataCenterId());
final Pod pod = _entityMgr.findById(Pod.class, storagePool.getPodId());
final ServiceOffering svo = _entityMgr.findById(ServiceOffering.class, vm.getServiceOfferingId());
final DiskOffering diskVO = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
final Long clusterId = storagePool.getClusterId();
VolumeInfo vol = null;
if (volume.getState() == Volume.State.Allocated) {
vol = createVolume(volume, vm, rootDiskTmplt, dcVO, pod, clusterId, svo, diskVO, new ArrayList<>(), volume.getSize(), rootDiskHyperType);
} else if (volume.getState() == Volume.State.Uploaded) {
vol = copyVolume(storagePool, volume, vm, rootDiskTmplt, dcVO, pod, diskVO, svo, rootDiskHyperType);
if (vol != null) {
// Moving of Volume is successful, decrement the volume resource count from secondary for an account and increment it into primary storage under same account.
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, volume.getSize());
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.getSize());
}
}
if (vol == null) {
throw new CloudRuntimeException("Volume shouldn't be null " + volume.getId());
}
final VolumeVO volVO = _volsDao.findById(vol.getId());
if (volVO.getFormat() == null) {
volVO.setFormat(getSupportedImageFormatForCluster(rootDiskHyperType));
}
_volsDao.update(volVO.getId(), volVO);
return volFactory.getVolume(volVO.getId());
}
use of com.cloud.engine.subsystem.api.storage.VolumeInfo in project cosmic by MissionCriticalCloud.
the class VolumeOrchestrator method createVolumeFromSnapshot.
@DB
@Override
public VolumeInfo createVolumeFromSnapshot(final Volume volume, final Snapshot snapshot, final UserVm vm) throws StorageUnavailableException {
final Account account = _entityMgr.findById(Account.class, volume.getAccountId());
final HashSet<StoragePool> poolsToAvoid = new HashSet<>();
StoragePool pool = null;
final Set<Long> podsToAvoid = new HashSet<>();
Pair<Pod, Long> pod = null;
final DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
final DataCenter dc = _entityMgr.findById(DataCenter.class, volume.getDataCenterId());
final DiskProfile dskCh = new DiskProfile(volume, diskOffering, snapshot.getHypervisorType());
String msg = "There are no available storage pools to store the volume in";
if (vm != null) {
final Pod podofVM = _entityMgr.findById(Pod.class, vm.getPodIdToDeployIn());
if (podofVM != null) {
pod = new Pair<>(podofVM, podofVM.getId());
}
}
if (vm != null && pod != null) {
// if VM is running use the hostId to find the clusterID. If it is stopped, refer the cluster where the ROOT volume of the VM exists.
Long hostId = null;
Long clusterId = null;
if (vm.getState() == State.Running) {
hostId = vm.getHostId();
if (hostId != null) {
final Host vmHost = _entityMgr.findById(Host.class, hostId);
clusterId = vmHost.getClusterId();
}
} else {
final List<VolumeVO> rootVolumesOfVm = _volsDao.findByInstanceAndType(vm.getId(), Volume.Type.ROOT);
if (rootVolumesOfVm.size() != 1) {
throw new CloudRuntimeException("The VM " + vm.getHostName() + " has more than one ROOT volume and is in an invalid state. Please contact Cloud Support.");
} else {
final VolumeVO rootVolumeOfVm = rootVolumesOfVm.get(0);
final StoragePoolVO rootDiskPool = _storagePoolDao.findById(rootVolumeOfVm.getPoolId());
clusterId = (rootDiskPool == null ? null : rootDiskPool.getClusterId());
}
}
// Determine what storage pool to store the volume in
while ((pool = findStoragePool(dskCh, dc, pod.first(), clusterId, hostId, vm, poolsToAvoid)) != null) {
break;
}
if (pool == null) {
// pool could not be found in the VM's pod/cluster.
if (s_logger.isDebugEnabled()) {
s_logger.debug("Could not find any storage pool to create Volume in the pod/cluster of the provided VM " + vm.getUuid());
}
final StringBuilder addDetails = new StringBuilder(msg);
addDetails.append(", Could not find any storage pool to create Volume in the pod/cluster of the VM ");
addDetails.append(vm.getUuid());
msg = addDetails.toString();
}
} else {
// Determine what pod to store the volume in
while ((pod = findPod(null, null, dc, account.getId(), podsToAvoid)) != null) {
podsToAvoid.add(pod.first().getId());
// Determine what storage pool to store the volume in
while ((pool = findStoragePool(dskCh, dc, pod.first(), null, null, null, poolsToAvoid)) != null) {
break;
}
if (pool != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Found a suitable pool for create volume: " + pool.getId());
}
break;
}
}
}
if (pool == null) {
s_logger.info(msg);
throw new StorageUnavailableException(msg, -1);
}
final VolumeInfo vol = volFactory.getVolume(volume.getId());
final DataStore store = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
final DataStoreRole dataStoreRole = getDataStoreRole(snapshot);
SnapshotInfo snapInfo = snapshotFactory.getSnapshot(snapshot.getId(), dataStoreRole);
if (snapInfo == null && dataStoreRole == DataStoreRole.Image) {
// snapshot is not backed up to secondary, let's do that now.
snapInfo = snapshotFactory.getSnapshot(snapshot.getId(), DataStoreRole.Primary);
if (snapInfo == null) {
throw new CloudRuntimeException("Cannot find snapshot " + snapshot.getId());
}
// We need to copy the snapshot onto secondary.
final 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");
}
}
// don't try to perform a sync if the DataStoreRole of the snapshot is equal to DataStoreRole.Primary
if (!DataStoreRole.Primary.equals(dataStoreRole)) {
try {
// sync snapshot to region store if necessary
final DataStore snapStore = snapInfo.getDataStore();
final long snapVolId = snapInfo.getVolumeId();
_snapshotSrv.syncVolumeSnapshotsToRegionStore(snapVolId, snapStore);
} catch (final Exception ex) {
// log but ignore the sync error to avoid any potential S3 down issue, it should be sync next time
s_logger.warn(ex.getMessage(), ex);
}
}
// create volume on primary from snapshot
final AsyncCallFuture<VolumeService.VolumeApiResult> future = volService.createVolumeFromSnapshot(vol, store, snapInfo);
try {
final VolumeService.VolumeApiResult result = future.get();
if (result.isFailed()) {
s_logger.debug("Failed to create volume from snapshot:" + result.getResult());
throw new CloudRuntimeException("Failed to create volume from snapshot:" + result.getResult());
}
return result.getVolume();
} catch (final InterruptedException e) {
s_logger.debug("Failed to create volume from snapshot", e);
throw new CloudRuntimeException("Failed to create volume from snapshot", e);
} catch (final ExecutionException e) {
s_logger.debug("Failed to create volume from snapshot", e);
throw new CloudRuntimeException("Failed to create volume from snapshot", e);
}
}
use of com.cloud.engine.subsystem.api.storage.VolumeInfo in project cosmic by MissionCriticalCloud.
the class StorageSystemDataMotionStrategy method copyAsync.
@Override
public Void copyAsync(final DataObject srcData, final DataObject destData, final Host destHost, final AsyncCompletionCallback<CopyCommandResult> callback) {
if (srcData instanceof SnapshotInfo) {
final SnapshotInfo snapshotInfo = (SnapshotInfo) srcData;
validate(snapshotInfo);
final boolean canHandleSrc = canHandle(srcData.getDataStore());
if (canHandleSrc && destData instanceof TemplateInfo && (destData.getDataStore().getRole() == DataStoreRole.Image || destData.getDataStore().getRole() == DataStoreRole.ImageCache)) {
return handleCreateTemplateFromSnapshot(snapshotInfo, (TemplateInfo) destData, callback);
}
if (destData instanceof VolumeInfo) {
final VolumeInfo volumeInfo = (VolumeInfo) destData;
final boolean canHandleDest = canHandle(destData.getDataStore());
if (canHandleSrc && canHandleDest) {
return handleCreateVolumeFromSnapshotBothOnStorageSystem(snapshotInfo, volumeInfo, callback);
}
if (canHandleSrc) {
throw new UnsupportedOperationException("This operation is not supported (DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT " + "not supported by destination storage plug-in).");
}
if (canHandleDest) {
throw new UnsupportedOperationException("This operation is not supported (DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT " + "not supported by source storage plug-in).");
}
}
}
throw new UnsupportedOperationException("This operation is not supported.");
}
use of com.cloud.engine.subsystem.api.storage.VolumeInfo in project cosmic by MissionCriticalCloud.
the class VMSnapshotHelperImpl method getVolumeTOList.
@Override
public List<VolumeObjectTO> getVolumeTOList(final Long vmId) {
final List<VolumeObjectTO> volumeTOs = new ArrayList<>();
final List<VolumeVO> volumeVOs = volumeDao.findByInstance(vmId);
for (final VolumeVO volume : volumeVOs) {
final VolumeInfo volumeInfo = volumeDataFactory.getVolume(volume.getId());
volumeTOs.add((VolumeObjectTO) volumeInfo.getTO());
}
return volumeTOs;
}
use of com.cloud.engine.subsystem.api.storage.VolumeInfo in project cosmic by MissionCriticalCloud.
the class AbstractHyperVisorStorageMotionStrategy method updateVolumePathsAfterMigration.
protected void updateVolumePathsAfterMigration(final Map<VolumeInfo, DataStore> volumeToPool, final List<VolumeObjectTO> volumeTos) {
for (final Map.Entry<VolumeInfo, DataStore> entry : volumeToPool.entrySet()) {
boolean updated = false;
final VolumeInfo volume = entry.getKey();
final StoragePool pool = (StoragePool) entry.getValue();
for (final VolumeObjectTO volumeTo : volumeTos) {
if (volume.getId() == volumeTo.getId()) {
final VolumeVO volumeVO = volDao.findById(volume.getId());
final Long oldPoolId = volumeVO.getPoolId();
volumeVO.setPath(volumeTo.getPath());
volumeVO.setFolder(pool.getPath());
volumeVO.setPodId(pool.getPodId());
volumeVO.setPoolId(pool.getId());
volumeVO.setLastPoolId(oldPoolId);
volDao.update(volume.getId(), volumeVO);
updated = true;
break;
}
}
if (!updated) {
s_logger.error("Volume path wasn't updated for volume " + volume + " after it was migrated.");
}
}
}
Aggregations