use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo in project cloudstack by apache.
the class VolumeApiServiceImpl method orchestrateResizeVolume.
private VolumeVO orchestrateResizeVolume(long volumeId, long currentSize, long newSize, Long newMinIops, Long newMaxIops, Integer newHypervisorSnapshotReserve, Long newDiskOfferingId, boolean shrinkOk) {
VolumeVO volume = _volsDao.findById(volumeId);
UserVmVO userVm = _userVmDao.findById(volume.getInstanceId());
StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
boolean isManaged = storagePool.isManaged();
/*
* get a list of hosts to send the commands to, try the system the
* associated vm is running on first, then the last known place it ran.
* If not attached to a userVm, we pass 'none' and resizevolume.sh is ok
* with that since it only needs the vm name to live resize
*/
long[] hosts = null;
String instanceName = "none";
if (userVm != null) {
instanceName = userVm.getInstanceName();
if (userVm.getHostId() != null) {
hosts = new long[] { userVm.getHostId() };
} else if (userVm.getLastHostId() != null) {
hosts = new long[] { userVm.getLastHostId() };
}
final String errorMsg = "The VM must be stopped or the disk detached in order to resize with the XenServer Hypervisor.";
if (storagePool.isManaged() && storagePool.getHypervisor() == HypervisorType.Any && hosts != null && hosts.length > 0) {
HostVO host = _hostDao.findById(hosts[0]);
if (currentSize != newSize && host.getHypervisorType() == HypervisorType.XenServer && !userVm.getState().equals(State.Stopped)) {
throw new InvalidParameterValueException(errorMsg);
}
}
/* Xen only works offline, SR does not support VDI.resizeOnline */
if (currentSize != newSize && _volsDao.getHypervisorType(volume.getId()) == HypervisorType.XenServer && !userVm.getState().equals(State.Stopped)) {
throw new InvalidParameterValueException(errorMsg);
}
}
ResizeVolumePayload payload = new ResizeVolumePayload(newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve, shrinkOk, instanceName, hosts, isManaged);
try {
VolumeInfo vol = volFactory.getVolume(volume.getId());
vol.addPayload(payload);
// this call to resize has a different impact depending on whether the
// underlying primary storage is managed or not
// if managed, this is the chance for the plug-in to change IOPS value, if applicable
// if not managed, this is the chance for the plug-in to talk to the hypervisor layer
// to change the size of the disk
AsyncCallFuture<VolumeApiResult> future = volService.resize(vol);
VolumeApiResult result = future.get();
// needs to tell the hypervisor to resize the disk
if (storagePool.isManaged() && currentSize != newSize) {
if (hosts != null && hosts.length > 0) {
volService.resizeVolumeOnHypervisor(volumeId, newSize, hosts[0], instanceName);
}
volume.setSize(newSize);
_volsDao.update(volume.getId(), volume);
}
if (result.isFailed()) {
s_logger.warn("Failed to resize the volume " + volume);
String details = "";
if (result.getResult() != null && !result.getResult().isEmpty()) {
details = result.getResult();
}
throw new CloudRuntimeException(details);
}
volume = _volsDao.findById(volume.getId());
if (newDiskOfferingId != null) {
volume.setDiskOfferingId(newDiskOfferingId);
}
if (currentSize != newSize) {
volume.setSize(newSize);
}
_volsDao.update(volume.getId(), volume);
/* Update resource count for the account on primary storage resource */
if (!shrinkOk) {
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplayVolume(), new Long(newSize - currentSize));
} else {
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplayVolume(), new Long(currentSize - newSize));
}
return volume;
} catch (InterruptedException e) {
s_logger.warn("failed get resize volume result", e);
throw new CloudRuntimeException(e.getMessage());
} catch (ExecutionException e) {
s_logger.warn("failed get resize volume result", e);
throw new CloudRuntimeException(e.getMessage());
} catch (Exception e) {
s_logger.warn("failed get resize volume result", e);
throw new CloudRuntimeException(e.getMessage());
}
}
use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo in project cloudstack by apache.
the class VolumeApiServiceImpl method allocSnapshot.
@Override
@ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_CREATE, eventDescription = "allocating snapshot", create = true)
public Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName, Snapshot.LocationType locationType) throws ResourceAllocationException {
Account caller = CallContext.current().getCallingAccount();
VolumeInfo volume = volFactory.getVolume(volumeId);
if (volume == null) {
throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist");
}
DataCenter zone = _dcDao.findById(volume.getDataCenterId());
if (zone == null) {
throw new InvalidParameterValueException("Can't find zone by id " + volume.getDataCenterId());
}
if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zone.getName());
}
if (volume.getState() != Volume.State.Ready) {
throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot.");
}
if (ImageFormat.DIR.equals(volume.getFormat())) {
throw new InvalidParameterValueException("Snapshot not supported for volume:" + volumeId);
}
if (volume.getTemplateId() != null) {
VMTemplateVO template = _templateDao.findById(volume.getTemplateId());
if (template != null && template.getTemplateType() == Storage.TemplateType.SYSTEM) {
throw new InvalidParameterValueException("VolumeId: " + volumeId + " is for System VM , Creating snapshot against System VM volumes is not supported");
}
}
StoragePoolVO storagePoolVO = _storagePoolDao.findById(volume.getPoolId());
if (!storagePoolVO.isManaged() && locationType != null) {
throw new InvalidParameterValueException("VolumeId: " + volumeId + " LocationType is supported only for managed storage");
}
if (storagePoolVO.isManaged() && locationType == null) {
locationType = Snapshot.LocationType.PRIMARY;
}
StoragePool storagePool = (StoragePool) volume.getDataStore();
if (storagePool == null) {
throw new InvalidParameterValueException("VolumeId: " + volumeId + " please attach this volume to a VM before create snapshot for it");
}
return snapshotMgr.allocSnapshot(volumeId, policyId, snapshotName, locationType);
}
use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo in project cloudstack by apache.
the class StorageManagerImpl method handleManagedStorage.
private void handleManagedStorage(Volume volume) {
Long instanceId = volume.getInstanceId();
// deleting the volume that supports it on a SAN. This only applies for managed storage.
if (instanceId != null) {
StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
if (storagePool != null && storagePool.isManaged()) {
DataTO volTO = volFactory.getVolume(volume.getId()).getTO();
DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getPath(), volume.getVolumeType());
DettachCommand cmd = new DettachCommand(disk, null);
cmd.setManaged(true);
cmd.setStorageHost(storagePool.getHostAddress());
cmd.setStoragePort(storagePool.getPort());
cmd.set_iScsiName(volume.get_iScsiName());
VMInstanceVO vmInstanceVO = _vmInstanceDao.findById(instanceId);
Long lastHostId = vmInstanceVO.getLastHostId();
if (lastHostId != null) {
Answer answer = _agentMgr.easySend(lastHostId, cmd);
if (answer != null && answer.getResult()) {
VolumeInfo volumeInfo = volFactory.getVolume(volume.getId());
HostVO host = _hostDao.findById(lastHostId);
volService.revokeAccess(volumeInfo, host, volumeInfo.getDataStore());
} else {
s_logger.warn("Unable to remove host-side clustered file system for the following volume: " + volume.getUuid());
}
}
}
}
}
use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo in project cloudstack by apache.
the class VmwareStorageMotionStrategyTest method testStrategyDoesnotHandlesNonVmwareHosts.
@Test
public void testStrategyDoesnotHandlesNonVmwareHosts() throws Exception {
Host srcHost = mock(Host.class);
Host destHost = mock(Host.class);
when(srcHost.getHypervisorType()).thenReturn(HypervisorType.XenServer);
when(destHost.getHypervisorType()).thenReturn(HypervisorType.XenServer);
Map<VolumeInfo, DataStore> volumeMap = new HashMap<VolumeInfo, DataStore>();
StrategyPriority canHandle = strategy.canHandle(volumeMap, srcHost, destHost);
assertFalse("The strategy is only supposed to handle vmware hosts", canHandle == StrategyPriority.HYPERVISOR);
}
use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo in project cloudstack by apache.
the class VmwareStorageMotionStrategyTest method testMigrateWithinClusterFailure.
@Test
public void testMigrateWithinClusterFailure() throws Exception {
Host srcHost = mock(Host.class);
Host destHost = mock(Host.class);
when(srcHost.getClusterId()).thenReturn(1L);
when(destHost.getClusterId()).thenReturn(1L);
Map<VolumeInfo, DataStore> volumeMap = new HashMap<VolumeInfo, DataStore>();
VirtualMachineTO to = mock(VirtualMachineTO.class);
when(to.getId()).thenReturn(6L);
VMInstanceVO instance = mock(VMInstanceVO.class);
when(instanceDao.findById(6L)).thenReturn(instance);
MockContext<CommandResult> context = new MockContext<CommandResult>(null, null, volumeMap);
AsyncCallbackDispatcher<VmwareStorageMotionStrategyTest, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().mockCallBack(null, null)).setContext(context);
MigrateWithStorageAnswer migAnswerMock = mock(MigrateWithStorageAnswer.class);
when(migAnswerMock.getResult()).thenReturn(false);
when(agentMgr.send(anyLong(), isA(MigrateWithStorageCommand.class))).thenReturn(migAnswerMock);
strategy.copyAsync(volumeMap, to, srcHost, destHost, caller);
assertFalse("Migration within cluster didn't fail.", result.isSuccess());
}
Aggregations