use of com.cloud.exception.StorageUnavailableException in project cosmic by MissionCriticalCloud.
the class VolumeApiServiceImpl method liveMigrateVolume.
@DB
protected Volume liveMigrateVolume(final Volume volume, final StoragePool destPool) throws StorageUnavailableException {
final VolumeInfo vol = volFactory.getVolume(volume.getId(), true);
final AsyncCallFuture<VolumeApiResult> future = volService.migrateVolume(vol, (DataStore) destPool);
try {
final VolumeApiResult result = future.get();
if (result.isFailed()) {
s_logger.debug("Live migrate volume failed:" + result.getResult());
throw new StorageUnavailableException("Live migrate volume failed: " + result.getResult(), destPool.getId());
}
return result.getVolume();
} catch (final InterruptedException e) {
s_logger.debug("Live migrate volume failed", e);
throw new CloudRuntimeException(e.getMessage());
} catch (final ExecutionException e) {
s_logger.debug("Live migrate volume failed", e);
throw new CloudRuntimeException(e.getMessage());
}
}
use of com.cloud.exception.StorageUnavailableException in project cosmic by MissionCriticalCloud.
the class VolumeApiServiceImpl method orchestrateAttachVolumeToVM.
private Volume orchestrateAttachVolumeToVM(final Long vmId, final Long volumeId, final Long deviceId) {
final VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
if (volumeToAttach.isAttachedVM()) {
throw new CloudRuntimeException("This volume is already attached to a VM.");
}
UserVmVO vm = _userVmDao.findById(vmId);
VolumeVO exstingVolumeOfVm = null;
final List<VolumeVO> rootVolumesOfVm = _volsDao.findByInstanceAndType(vmId, 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.");
} else {
if (!rootVolumesOfVm.isEmpty()) {
exstingVolumeOfVm = rootVolumesOfVm.get(0);
} else {
// locate data volume of the vm
final List<VolumeVO> diskVolumesOfVm = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
for (final VolumeVO diskVolume : diskVolumesOfVm) {
if (diskVolume.getState() != Volume.State.Allocated) {
exstingVolumeOfVm = diskVolume;
break;
}
}
}
}
final HypervisorType rootDiskHyperType = vm.getHypervisorType();
final HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
VolumeInfo newVolumeOnPrimaryStorage = volumeToAttach;
// don't create volume on primary storage if its being attached to the vm which Root's volume hasn't been created yet
StoragePoolVO destPrimaryStorage = null;
if (exstingVolumeOfVm != null && !exstingVolumeOfVm.getState().equals(Volume.State.Allocated)) {
destPrimaryStorage = _storagePoolDao.findById(exstingVolumeOfVm.getPoolId());
}
final boolean volumeOnSecondary = volumeToAttach.getState() == Volume.State.Uploaded;
if (destPrimaryStorage != null && (volumeToAttach.getState() == Volume.State.Allocated || volumeOnSecondary)) {
try {
newVolumeOnPrimaryStorage = _volumeMgr.createVolumeOnPrimaryStorage(vm, volumeToAttach, rootDiskHyperType, destPrimaryStorage);
} catch (final NoTransitionException e) {
s_logger.debug("Failed to create volume on primary storage", e);
throw new CloudRuntimeException("Failed to create volume on primary storage", e);
}
}
// reload the volume from db
newVolumeOnPrimaryStorage = volFactory.getVolume(newVolumeOnPrimaryStorage.getId());
final boolean moveVolumeNeeded = needMoveVolume(exstingVolumeOfVm, newVolumeOnPrimaryStorage);
if (moveVolumeNeeded) {
final PrimaryDataStoreInfo primaryStore = (PrimaryDataStoreInfo) newVolumeOnPrimaryStorage.getDataStore();
if (primaryStore.isLocal()) {
throw new CloudRuntimeException("Failed to attach local data volume " + volumeToAttach.getName() + " to VM " + vm.getDisplayName() + " as migration of local data volume is not allowed");
}
final StoragePoolVO vmRootVolumePool = _storagePoolDao.findById(exstingVolumeOfVm.getPoolId());
try {
newVolumeOnPrimaryStorage = _volumeMgr.moveVolume(newVolumeOnPrimaryStorage, vmRootVolumePool.getDataCenterId(), vmRootVolumePool.getPodId(), vmRootVolumePool.getClusterId(), volumeToAttachHyperType);
} catch (final ConcurrentOperationException e) {
s_logger.debug("move volume failed", e);
throw new CloudRuntimeException("move volume failed", e);
} catch (final StorageUnavailableException e) {
s_logger.debug("move volume failed", e);
throw new CloudRuntimeException("move volume failed", e);
}
}
VolumeVO newVol = _volsDao.findById(newVolumeOnPrimaryStorage.getId());
// Getting the fresh vm object in case of volume migration to check the current state of VM
if (moveVolumeNeeded || volumeOnSecondary) {
vm = _userVmDao.findById(vmId);
if (vm == null) {
throw new InvalidParameterValueException("VM not found.");
}
}
newVol = sendAttachVolumeCommand(vm, newVol, deviceId);
return newVol;
}
use of com.cloud.exception.StorageUnavailableException in project cloudstack by apache.
the class VolumeOrchestrator method prepare.
@Override
public void prepare(VirtualMachineProfile vm, DeployDestination dest) throws StorageUnavailableException, InsufficientStorageCapacityException, ConcurrentOperationException, StorageAccessException {
if (dest == null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("DeployDestination cannot be null, cannot prepare Volumes for the vm: " + vm);
}
throw new CloudRuntimeException("Unable to prepare Volume for vm because DeployDestination is null, vm:" + vm);
}
// don't allow to start vm that doesn't have a root volume
if (_volsDao.findByInstanceAndType(vm.getId(), Volume.Type.ROOT).isEmpty()) {
throw new CloudRuntimeException("Unable to prepare volumes for vm as ROOT volume is missing");
}
List<VolumeVO> vols = _volsDao.findUsableVolumesForInstance(vm.getId());
List<VolumeTask> tasks = getTasks(vols, dest.getStorageForDisks(), vm);
Volume vol = null;
StoragePool pool;
for (VolumeTask task : tasks) {
if (task.type == VolumeTaskType.NOP) {
vol = task.volume;
pool = (StoragePool) dataStoreMgr.getDataStore(task.pool.getId(), DataStoreRole.Primary);
// cluster. In that case, make sure that the volume is in the right access group.
if (pool.isManaged()) {
Host lastHost = _hostDao.findById(vm.getVirtualMachine().getLastHostId());
Host host = _hostDao.findById(vm.getVirtualMachine().getHostId());
long lastClusterId = lastHost == null || lastHost.getClusterId() == null ? -1 : lastHost.getClusterId();
long clusterId = host == null || host.getClusterId() == null ? -1 : host.getClusterId();
if (lastClusterId != clusterId) {
if (lastHost != null) {
storageMgr.removeStoragePoolFromCluster(lastHost.getId(), vol.get_iScsiName(), pool);
DataStore storagePool = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
volService.revokeAccess(volFactory.getVolume(vol.getId()), lastHost, storagePool);
}
try {
volService.grantAccess(volFactory.getVolume(vol.getId()), host, (DataStore) pool);
} catch (Exception e) {
throw new StorageAccessException("Unable to grant access to volume: " + vol.getId() + " on host: " + host.getId());
}
} else {
// This might impact other managed storages, grant access for PowerFlex storage pool only
if (pool.getPoolType() == Storage.StoragePoolType.PowerFlex) {
try {
volService.grantAccess(volFactory.getVolume(vol.getId()), host, (DataStore) pool);
} catch (Exception e) {
throw new StorageAccessException("Unable to grant access to volume: " + vol.getId() + " on host: " + host.getId());
}
}
}
}
} else if (task.type == VolumeTaskType.MIGRATE) {
pool = (StoragePool) dataStoreMgr.getDataStore(task.pool.getId(), DataStoreRole.Primary);
vol = migrateVolume(task.volume, pool);
} else if (task.type == VolumeTaskType.RECREATE) {
Pair<VolumeVO, DataStore> result = recreateVolume(task.volume, vm, dest);
pool = (StoragePool) dataStoreMgr.getDataStore(result.second().getId(), DataStoreRole.Primary);
vol = result.first();
}
VolumeInfo volumeInfo = volFactory.getVolume(vol.getId());
DataTO volTO = volumeInfo.getTO();
DiskTO disk = storageMgr.getDiskWithThrottling(volTO, vol.getVolumeType(), vol.getDeviceId(), vol.getPath(), vm.getServiceOfferingId(), vol.getDiskOfferingId());
DataStore dataStore = dataStoreMgr.getDataStore(vol.getPoolId(), DataStoreRole.Primary);
disk.setDetails(getDetails(volumeInfo, dataStore));
vm.addDisk(disk);
// If hypervisor is vSphere, check for clone type setting.
if (vm.getHypervisorType().equals(HypervisorType.VMware)) {
// retrieve clone flag.
UserVmCloneType cloneType = UserVmCloneType.linked;
Boolean value = CapacityManager.VmwareCreateCloneFull.valueIn(vol.getPoolId());
if (value != null && value) {
cloneType = UserVmCloneType.full;
}
UserVmCloneSettingVO cloneSettingVO = _vmCloneSettingDao.findByVmId(vm.getId());
if (cloneSettingVO != null) {
if (!cloneSettingVO.getCloneType().equals(cloneType.toString())) {
cloneSettingVO.setCloneType(cloneType.toString());
_vmCloneSettingDao.update(cloneSettingVO.getId(), cloneSettingVO);
}
} else {
UserVmCloneSettingVO vmCloneSettingVO = new UserVmCloneSettingVO(vm.getId(), cloneType.toString());
_vmCloneSettingDao.persist(vmCloneSettingVO);
}
}
}
}
use of com.cloud.exception.StorageUnavailableException 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);
}
use of com.cloud.exception.StorageUnavailableException in project cloudstack by apache.
the class VolumeOrchestrator method migrateVolume.
@Override
@DB
public Volume migrateVolume(Volume volume, StoragePool destPool) throws StorageUnavailableException {
VolumeInfo vol = volFactory.getVolume(volume.getId());
if (vol == null) {
throw new CloudRuntimeException("Migrate volume failed because volume object of volume " + volume.getName() + "is null");
}
if (destPool == null) {
throw new CloudRuntimeException("Migrate volume failed because destination storage pool is not available!!");
}
checkConcurrentJobsPerDatastoreThreshhold(destPool);
DataStore dataStoreTarget = dataStoreMgr.getDataStore(destPool.getId(), DataStoreRole.Primary);
AsyncCallFuture<VolumeApiResult> future = volService.copyVolume(vol, dataStoreTarget);
try {
VolumeApiResult result = future.get();
if (result.isFailed()) {
s_logger.error("Migrate volume failed:" + result.getResult());
if (result.getResult() != null && result.getResult().contains("[UNSUPPORTED]")) {
throw new CloudRuntimeException("Migrate volume failed: " + result.getResult());
}
throw new StorageUnavailableException("Migrate volume failed: " + result.getResult(), destPool.getId());
} else {
// update the volumeId for snapshots on secondary
if (!_snapshotDao.listByVolumeId(vol.getId()).isEmpty()) {
_snapshotDao.updateVolumeIds(vol.getId(), result.getVolume().getId());
_snapshotDataStoreDao.updateVolumeIds(vol.getId(), result.getVolume().getId());
}
}
return result.getVolume();
} catch (InterruptedException e) {
s_logger.debug("migrate volume failed", e);
throw new CloudRuntimeException(e.getMessage());
} catch (ExecutionException e) {
s_logger.debug("migrate volume failed", e);
throw new CloudRuntimeException(e.getMessage());
}
}
Aggregations