use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult in project cloudstack by apache.
the class VolumeApiServiceImpl method liveMigrateVolume.
@DB
protected Volume liveMigrateVolume(Volume volume, StoragePool destPool) throws StorageUnavailableException {
VolumeInfo vol = volFactory.getVolume(volume.getId());
AsyncCallFuture<VolumeApiResult> future = volService.migrateVolume(vol, (DataStore) destPool);
try {
VolumeApiResult result = future.get();
if (result.isFailed()) {
s_logger.debug("migrate volume failed:" + result.getResult());
throw new StorageUnavailableException("Migrate volume failed: " + result.getResult(), destPool.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());
}
}
use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult in project cloudstack by apache.
the class StorageManagerImpl method cleanupStorage.
@Override
public void cleanupStorage(boolean recurring) {
GlobalLock scanLock = GlobalLock.getInternLock("storagemgr.cleanup");
try {
if (scanLock.lock(3)) {
try {
// Cleanup primary storage pools
if (_templateCleanupEnabled) {
List<StoragePoolVO> storagePools = _storagePoolDao.listAll();
for (StoragePoolVO pool : storagePools) {
try {
List<VMTemplateStoragePoolVO> unusedTemplatesInPool = _tmpltMgr.getUnusedTemplatesInPool(pool);
s_logger.debug("Storage pool garbage collector found " + unusedTemplatesInPool.size() + " templates to clean up in storage pool: " + pool.getName());
for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) {
if (templatePoolVO.getDownloadState() != VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
s_logger.debug("Storage pool garbage collector is skipping template with ID: " + templatePoolVO.getTemplateId() + " on pool " + templatePoolVO.getPoolId() + " because it is not completely downloaded.");
continue;
}
if (!templatePoolVO.getMarkedForGC()) {
templatePoolVO.setMarkedForGC(true);
_vmTemplatePoolDao.update(templatePoolVO.getId(), templatePoolVO);
s_logger.debug("Storage pool garbage collector has marked template with ID: " + templatePoolVO.getTemplateId() + " on pool " + templatePoolVO.getPoolId() + " for garbage collection.");
continue;
}
_tmpltMgr.evictTemplateFromStoragePool(templatePoolVO);
}
} catch (Exception e) {
s_logger.warn("Problem cleaning up primary storage pool " + pool, e);
}
}
}
cleanupSecondaryStorage(recurring);
List<VolumeVO> vols = _volsDao.listVolumesToBeDestroyed(new Date(System.currentTimeMillis() - ((long) StorageCleanupDelay.value() << 10)));
for (VolumeVO vol : vols) {
try {
// If this fails, just log a warning. It's ideal if we clean up the host-side clustered file
// system, but not necessary.
handleManagedStorage(vol);
} catch (Exception e) {
s_logger.warn("Unable to destroy host-side clustered file system " + vol.getUuid(), e);
}
try {
VolumeInfo volumeInfo = volFactory.getVolume(vol.getId());
if (volumeInfo != null) {
volService.expungeVolumeAsync(volumeInfo);
} else {
s_logger.debug("Volume " + vol.getUuid() + " is already destroyed");
}
} catch (Exception e) {
s_logger.warn("Unable to destroy volume " + vol.getUuid(), e);
}
}
// remove snapshots in Error state
List<SnapshotVO> snapshots = _snapshotDao.listAllByStatus(Snapshot.State.Error);
for (SnapshotVO snapshotVO : snapshots) {
try {
List<SnapshotDataStoreVO> storeRefs = _snapshotStoreDao.findBySnapshotId(snapshotVO.getId());
for (SnapshotDataStoreVO ref : storeRefs) {
_snapshotStoreDao.expunge(ref.getId());
}
_snapshotDao.expunge(snapshotVO.getId());
} catch (Exception e) {
s_logger.warn("Unable to destroy snapshot " + snapshotVO.getUuid(), e);
}
}
// destroy uploaded volumes in abandoned/error state
List<VolumeDataStoreVO> volumeDataStores = _volumeDataStoreDao.listByVolumeState(Volume.State.UploadError, Volume.State.UploadAbandoned);
for (VolumeDataStoreVO volumeDataStore : volumeDataStores) {
VolumeVO volume = _volumeDao.findById(volumeDataStore.getVolumeId());
if (volume == null) {
s_logger.warn("Uploaded volume with id " + volumeDataStore.getVolumeId() + " not found, so cannot be destroyed");
continue;
}
try {
DataStore dataStore = _dataStoreMgr.getDataStore(volumeDataStore.getDataStoreId(), DataStoreRole.Image);
EndPoint ep = _epSelector.select(dataStore, volumeDataStore.getExtractUrl());
if (ep == null) {
s_logger.warn("There is no secondary storage VM for image store " + dataStore.getName() + ", cannot destroy uploaded volume " + volume.getUuid());
continue;
}
Host host = _hostDao.findById(ep.getId());
if (host != null && host.getManagementServerId() != null) {
if (_serverId == host.getManagementServerId().longValue()) {
if (!volService.destroyVolume(volume.getId())) {
s_logger.warn("Unable to destroy uploaded volume " + volume.getUuid());
continue;
}
// decrement volume resource count
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplayVolume());
// expunge volume from secondary if volume is on image store
VolumeInfo volOnSecondary = volFactory.getVolume(volume.getId(), DataStoreRole.Image);
if (volOnSecondary != null) {
s_logger.info("Expunging volume " + volume.getUuid() + " uploaded using HTTP POST from secondary data store");
AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volOnSecondary);
VolumeApiResult result = future.get();
if (!result.isSuccess()) {
s_logger.warn("Failed to expunge volume " + volume.getUuid() + " from the image store " + dataStore.getName() + " due to: " + result.getResult());
}
}
}
}
} catch (Throwable th) {
s_logger.warn("Unable to destroy uploaded volume " + volume.getUuid() + ". Error details: " + th.getMessage());
}
}
// destroy uploaded templates in abandoned/error state
List<TemplateDataStoreVO> templateDataStores = _templateStoreDao.listByTemplateState(VirtualMachineTemplate.State.UploadError, VirtualMachineTemplate.State.UploadAbandoned);
for (TemplateDataStoreVO templateDataStore : templateDataStores) {
VMTemplateVO template = _templateDao.findById(templateDataStore.getTemplateId());
if (template == null) {
s_logger.warn("Uploaded template with id " + templateDataStore.getTemplateId() + " not found, so cannot be destroyed");
continue;
}
try {
DataStore dataStore = _dataStoreMgr.getDataStore(templateDataStore.getDataStoreId(), DataStoreRole.Image);
EndPoint ep = _epSelector.select(dataStore, templateDataStore.getExtractUrl());
if (ep == null) {
s_logger.warn("There is no secondary storage VM for image store " + dataStore.getName() + ", cannot destroy uploaded template " + template.getUuid());
continue;
}
Host host = _hostDao.findById(ep.getId());
if (host != null && host.getManagementServerId() != null) {
if (_serverId == host.getManagementServerId().longValue()) {
AsyncCallFuture<TemplateApiResult> future = _imageSrv.deleteTemplateAsync(tmplFactory.getTemplate(template.getId(), dataStore));
TemplateApiResult result = future.get();
if (!result.isSuccess()) {
s_logger.warn("Failed to delete template " + template.getUuid() + " from the image store " + dataStore.getName() + " due to: " + result.getResult());
continue;
}
// remove from template_zone_ref
List<VMTemplateZoneVO> templateZones = _vmTemplateZoneDao.listByZoneTemplate(((ImageStoreEntity) dataStore).getDataCenterId(), template.getId());
if (templateZones != null) {
for (VMTemplateZoneVO templateZone : templateZones) {
_vmTemplateZoneDao.remove(templateZone.getId());
}
}
// mark all the occurrences of this template in the given store as destroyed
_templateStoreDao.removeByTemplateStore(template.getId(), dataStore.getId());
// find all eligible image stores for this template
List<DataStore> imageStores = _tmpltMgr.getImageStoreByTemplate(template.getId(), null);
if (imageStores == null || imageStores.size() == 0) {
template.setState(VirtualMachineTemplate.State.Inactive);
_templateDao.update(template.getId(), template);
// decrement template resource count
_resourceLimitMgr.decrementResourceCount(template.getAccountId(), ResourceType.template);
}
}
}
} catch (Throwable th) {
s_logger.warn("Unable to destroy uploaded template " + template.getUuid() + ". Error details: " + th.getMessage());
}
}
} finally {
scanLock.unlock();
}
}
} finally {
scanLock.releaseRef();
}
}
use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult in project cloudstack by apache.
the class VolumeApiServiceImpl method orchestrateExtractVolume.
private String orchestrateExtractVolume(long volumeId, long zoneId) {
// get latest volume state to make sure that it is not updated by other parallel operations
VolumeVO volume = _volsDao.findById(volumeId);
if (volume == null || volume.getState() != Volume.State.Ready) {
throw new InvalidParameterValueException("Volume to be extracted has been removed or not in right state!");
}
// perform extraction
ImageStoreEntity secStore = (ImageStoreEntity) dataStoreMgr.getImageStore(zoneId);
String value = _configDao.getValue(Config.CopyVolumeWait.toString());
NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue()));
// Copy volume from primary to secondary storage
VolumeInfo srcVol = volFactory.getVolume(volumeId);
AsyncCallFuture<VolumeApiResult> cvAnswer = volService.copyVolume(srcVol, secStore);
// Check if you got a valid answer.
VolumeApiResult cvResult = null;
try {
cvResult = cvAnswer.get();
} catch (InterruptedException e1) {
s_logger.debug("failed copy volume", e1);
throw new CloudRuntimeException("Failed to copy volume", e1);
} catch (ExecutionException e1) {
s_logger.debug("failed copy volume", e1);
throw new CloudRuntimeException("Failed to copy volume", e1);
}
if (cvResult == null || cvResult.isFailed()) {
String errorString = "Failed to copy the volume from the source primary storage pool to secondary storage.";
throw new CloudRuntimeException(errorString);
}
VolumeInfo vol = cvResult.getVolume();
String extractUrl = secStore.createEntityExtractUrl(vol.getPath(), vol.getFormat(), vol);
VolumeDataStoreVO volumeStoreRef = _volumeStoreDao.findByVolume(volumeId);
volumeStoreRef.setExtractUrl(extractUrl);
volumeStoreRef.setExtractUrlCreated(DateUtil.now());
_volumeStoreDao.update(volumeStoreRef.getId(), volumeStoreRef);
return extractUrl;
}
use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult 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());
}
}
Aggregations