@Override public VolumeInfo getBaseVolume() { return volFactory.getVolume(snapshot.getVolumeId()); }
@Override public List<VolumeObjectTO> getVolumeTOList(Long vmId) { List<VolumeObjectTO> volumeTOs = new ArrayList<VolumeObjectTO>(); List<VolumeVO> volumeVos = volumeDao.findByInstance(vmId); VolumeInfo volumeInfo = null; for (VolumeVO volume : volumeVos) { volumeInfo = volumeDataFactory.getVolume(volume.getId()); volumeTOs.add((VolumeObjectTO)volumeInfo.getTO()); } return volumeTOs; }
private List<VolumeObjectTO> getVolumeTOList(Long vmId) { List<VolumeObjectTO> volumeTOs = new ArrayList<VolumeObjectTO>(); List<VolumeVO> volumeVos = _volumeDao.findByInstance(vmId); VolumeInfo volumeInfo = null; for (VolumeVO volume : volumeVos) { volumeInfo = volumeDataFactory.getVolume(volume.getId()); volumeTOs.add((VolumeObjectTO)volumeInfo.getTO()); } return volumeTOs; }
/** * We will check if the given volume is in the primary storage. If it is, we will execute an asynchronous call to delete it there. * If the volume is not in the primary storage, we do nothing here. */ protected void expungeVolumesInPrimaryStorageIfNeeded(VolumeVO volume) throws InterruptedException, ExecutionException { VolumeInfo volOnPrimary = volFactory.getVolume(volume.getId(), DataStoreRole.Primary); if (volOnPrimary != null) { s_logger.info("Expunging volume " + volume.getId() + " from primary data store"); AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volOnPrimary); future.get(); } }
@DB @Override public void destroyVolume(long volumeId) { // mark volume entry in volumes table as destroy state VolumeInfo vol = volFactory.getVolume(volumeId); vol.stateTransit(Volume.Event.DestroyRequested); snapshotMgr.deletePoliciesForVolume(volumeId); vol.stateTransit(Volume.Event.OperationSucceeded); }
@DB protected Volume liveMigrateVolume(Volume volume, StoragePool destPool) { 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()); return null; } return result.getVolume(); } catch (InterruptedException e) { s_logger.debug("migrate volume failed", e); return null; } catch (ExecutionException e) { s_logger.debug("migrate volume failed", e); return null; } }
/** * We will check if the given volume is in the secondary storage. If the volume is not in the primary storage, we do nothing here. * If it is, we will execute an asynchronous call to delete it there. Then, we decrement the {@link ResourceType#secondary_storage} for the account that owns the volume. */ protected void expungeVolumesInSecondaryStorageIfNeeded(VolumeVO volume) throws InterruptedException, ExecutionException { VolumeInfo volOnSecondary = volFactory.getVolume(volume.getId(), DataStoreRole.Image); if (volOnSecondary != null) { s_logger.info("Expunging volume " + volume.getId() + " from secondary data store"); AsyncCallFuture<VolumeApiResult> future2 = volService.expungeVolumeAsync(volOnSecondary); future2.get(); _resourceLimitMgr.decrementResourceCount(volOnSecondary.getAccountId(), ResourceType.secondary_storage, volOnSecondary.getSize()); } }
@Override public VolumeVO doInTransaction(TransactionStatus status) { VolumeVO newVolume = allocateDuplicateVolumeVO(existingVolume, templateIdToUseFinal); try { stateTransitTo(existingVolume, Volume.Event.DestroyRequested); } catch (NoTransitionException e) { s_logger.debug("Unable to destroy existing volume: " + e.toString()); } // In case of VMware VM will continue to use the old root disk until expunged, so force expunge old root disk if (vm.getHypervisorType() == HypervisorType.VMware) { s_logger.info("Expunging volume " + existingVolume.getId() + " from primary data store"); AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volFactory.getVolume(existingVolume.getId())); try { future.get(); } catch (Exception e) { s_logger.debug("Failed to expunge volume:" + existingVolume.getId(), e); } } return newVolume; } });
private void verifySufficientBytesForStoragePool(long storagePoolId, long volumeId, long newSize, Integer newHypervisorSnapshotReserve) { DataStore primaryDataStore = dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary); VolumeInfo volumeInfo = volumeFactory.getVolume(volumeId, primaryDataStore); StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId); long currentSizeWithHsr = getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeInfo, storagePool); newHypervisorSnapshotReserve = newHypervisorSnapshotReserve == null ? LOWEST_HYPERVISOR_SNAPSHOT_RESERVE : Math.max(newHypervisorSnapshotReserve, LOWEST_HYPERVISOR_SNAPSHOT_RESERVE); long newSizeWithHsr = (long)(newSize + newSize * (newHypervisorSnapshotReserve / 100f)); if (newSizeWithHsr < currentSizeWithHsr) { throw new CloudRuntimeException("Storage pool " + storagePoolId + " does not support shrinking a volume."); } long availableBytes = storagePool.getCapacityBytes() - getUsedBytes(storagePool); if ((newSizeWithHsr - currentSizeWithHsr) > availableBytes) { throw new CloudRuntimeException("Storage pool " + storagePoolId + " does not have enough space to expand the volume."); } }
@Override public VolumeInfo updateHypervisorSnapshotReserveForVolume(DiskOffering diskOffering, long volumeId, HypervisorType hyperType) { if (diskOffering != null && hyperType != null) { Integer hypervisorSnapshotReserve = diskOffering.getHypervisorSnapshotReserve(); if (hyperType == HypervisorType.KVM) { hypervisorSnapshotReserve = null; } else if (hypervisorSnapshotReserve == null || hypervisorSnapshotReserve < 0) { hypervisorSnapshotReserve = 0; } VolumeVO volume = volDao.findById(volumeId); volume.setHypervisorSnapshotReserve(hypervisorSnapshotReserve); volDao.update(volume.getId(), volume); } return volFactory.getVolume(volumeId); } }
private long getDataObjectSizeIncludingHypervisorSnapshotReserve(Volume volume, StoragePool pool) { DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName()); DataStoreDriver storeDriver = storeProvider.getDataStoreDriver(); if (storeDriver instanceof PrimaryDataStoreDriver) { PrimaryDataStoreDriver primaryStoreDriver = (PrimaryDataStoreDriver)storeDriver; VolumeInfo volumeInfo = volFactory.getVolume(volume.getId()); return primaryStoreDriver.getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeInfo, pool); } return volume.getSize(); }
@Override public DataObject get(DataObject dataObj, DataStore store) { if (dataObj.getType() == DataObjectType.TEMPLATE) { return imageFactory.getTemplate(dataObj, store); } else if (dataObj.getType() == DataObjectType.VOLUME) { return volumeFactory.getVolume(dataObj, store); } else if (dataObj.getType() == DataObjectType.SNAPSHOT) { return snapshotFactory.getSnapshot(dataObj, store); } throw new CloudRuntimeException("unknown type"); }
@DB protected Volume liveMigrateVolume(Volume volume, StoragePool destPool) throws StorageUnavailableException { VolumeInfo vol = volFactory.getVolume(volume.getId()); DataStore dataStoreTarget = dataStoreMgr.getDataStore(destPool.getId(), DataStoreRole.Primary); AsyncCallFuture<VolumeApiResult> future = volService.migrateVolume(vol, dataStoreTarget); 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()); } }
@Override public void revokeAccess(long vmId, long hostId) { HostVO host = _hostDao.findById(hostId); List<VolumeVO> volumesForVm = _volsDao.findByInstance(vmId); if (volumesForVm != null) { for (VolumeVO volumeForVm : volumesForVm) { VolumeInfo volumeInfo = volFactory.getVolume(volumeForVm.getId()); // pool id can be null for the VM's volumes in Allocated state if (volumeForVm.getPoolId() != null) { DataStore dataStore = dataStoreMgr.getDataStore(volumeForVm.getPoolId(), DataStoreRole.Primary); volService.revokeAccess(volumeInfo, host, dataStore); } } } }
private synchronized void checkAndSetAttaching(Long volumeId, Long hostId) { VolumeInfo volumeToAttach = volFactory.getVolume(volumeId); if (volumeToAttach.isAttachedVM()) { throw new CloudRuntimeException("volume: " + volumeToAttach.getName() + " is already attached to a VM: " + volumeToAttach.getAttachedVmName()); } if (volumeToAttach.getState().equals(Volume.State.Ready)) { volumeToAttach.stateTransit(Volume.Event.AttachRequested); } else { String error = null; if (hostId == null) { error = "Please try attach operation after starting VM once"; } else { error = "Volume: " + volumeToAttach.getName() + " is in " + volumeToAttach.getState() + ". It should be in Ready state"; } s_logger.error(error); throw new CloudRuntimeException(error); } }
@Override public void prepareForMigration(VirtualMachineProfile vm, DeployDestination dest) { List<VolumeVO> vols = _volsDao.findUsableVolumesForInstance(vm.getId()); if (s_logger.isDebugEnabled()) { s_logger.debug("Preparing " + vols.size() + " volumes for " + vm); } for (VolumeVO vol : vols) { 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 (vm.getType() == VirtualMachine.Type.User && vm.getTemplate().getFormat() == ImageFormat.ISO) { if (vm.getType() == VirtualMachine.Type.User) { _tmpltMgr.prepareIsoForVmProfile(vm, dest); //DataTO dataTO = tmplFactory.getTemplate(vm.getTemplate().getId(), DataStoreRole.Image, vm.getVirtualMachine().getDataCenterId()).getTO(); //DiskTO iso = new DiskTO(dataTO, 3L, null, Volume.Type.ISO); //vm.addDisk(iso); } }
@Override public VolumeInfo moveVolume(VolumeInfo volume, long destPoolDcId, Long destPoolPodId, Long destPoolClusterId, HypervisorType dataDiskHyperType) throws ConcurrentOperationException, StorageUnavailableException { // Find a destination storage pool with the specified criteria DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId()); DiskProfile dskCh = new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), diskOffering.getDiskSize(), diskOffering.getTagsArray(), diskOffering.isUseLocalStorage(), diskOffering.isRecreatable(), null); dskCh.setHyperType(dataDiskHyperType); storageMgr.setDiskProfileThrottling(dskCh, null, diskOffering); DataCenter destPoolDataCenter = _entityMgr.findById(DataCenter.class, destPoolDcId); Pod destPoolPod = _entityMgr.findById(Pod.class, destPoolPodId); StoragePool destPool = findStoragePool(dskCh, destPoolDataCenter, destPoolPod, destPoolClusterId, null, null, new HashSet<StoragePool>()); if (destPool == null) { throw new CloudRuntimeException("Failed to find a storage pool with enough capacity to move the volume to."); } Volume newVol = migrateVolume(volume, destPool); return volFactory.getVolume(newVol.getId()); }
private Snapshot orchestrateTakeVolumeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account account, boolean quiescevm, Snapshot.LocationType locationType, boolean asyncBackup) throws ResourceAllocationException { VolumeInfo volume = volFactory.getVolume(volumeId); if (volume == null) { throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist"); } if (volume.getState() != Volume.State.Ready) { throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot."); } CreateSnapshotPayload payload = new CreateSnapshotPayload(); payload.setSnapshotId(snapshotId); payload.setSnapshotPolicyId(policyId); payload.setAccount(account); payload.setQuiescevm(quiescevm); payload.setLocationType(locationType); payload.setAsyncBackup(asyncBackup); volume.addPayload(payload); return volService.takeSnapshot(volume); }
@Override public AsyncCallFuture<VolumeApiResult> registerVolume(VolumeInfo volume, DataStore store) { AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>(); DataObject volumeOnStore = store.create(volume); volumeOnStore.processEvent(Event.CreateOnlyRequested); try { CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volumeOnStore, future); AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().registerVolumeCallback(null, null)); caller.setContext(context); store.getDriver().createAsync(store, volumeOnStore, caller); } catch (CloudRuntimeException ex) { // clean up already persisted volume_store_ref entry in case of createVolumeCallback is never called VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), volume.getId()); if (volStoreVO != null) { VolumeInfo volObj = volFactory.getVolume(volume, store); volObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed); } VolumeApiResult res = new VolumeApiResult((VolumeObject)volumeOnStore); res.setResult(ex.getMessage()); future.complete(res); } return future; }
@Override @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPLOAD, eventDescription = "uploading volume", async = true) public VolumeVO uploadVolume(UploadVolumeCmd cmd) throws ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); long ownerId = cmd.getEntityOwnerId(); Account owner = _entityMgr.findById(Account.class, ownerId); Long zoneId = cmd.getZoneId(); String volumeName = cmd.getVolumeName(); String url = cmd.getUrl(); String format = cmd.getFormat(); Long diskOfferingId = cmd.getDiskOfferingId(); String imageStoreUuid = cmd.getImageStoreUuid(); DataStore store = _tmpltMgr.getImageStore(imageStoreUuid, zoneId); validateVolume(caller, ownerId, zoneId, volumeName, url, format, diskOfferingId); VolumeVO volume = persistVolume(owner, zoneId, volumeName, url, cmd.getFormat(), diskOfferingId, Volume.State.Allocated); VolumeInfo vol = volFactory.getVolume(volume.getId()); RegisterVolumePayload payload = new RegisterVolumePayload(cmd.getUrl(), cmd.getChecksum(), cmd.getFormat()); vol.addPayload(payload); volService.registerVolume(vol, store); return volume; }