Github user DaanHoogland commented on a diff in the pull request: https://github.com/apache/cloudstack/pull/1403#discussion_r62890766 --- Diff: plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java --- @@ -665,22 +950,190 @@ private void updateSnapshotDetails(long csSnapshotId, long sfNewVolumeId, long s _snapshotDetailsDao.persist(snapshotDetail); } - // return null for no error message - private String deleteSnapshot(SnapshotInfo snapshotInfo, long storagePoolId) { - String errMsg = null; + private String createVolume(VolumeInfo volumeInfo, long storagePoolId) { + verifySufficientBytesForStoragePool(volumeInfo, storagePoolId); + verifySufficientIopsForStoragePool(volumeInfo.getMinIops() != null ? volumeInfo.getMinIops() : getDefaultMinIops(storagePoolId), storagePoolId); + + SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, _storagePoolDetailsDao); + + long sfAccountId = getCreateSolidFireAccountId(sfConnection, volumeInfo.getAccountId(), storagePoolId); + + long csSnapshotId = getCsIdForCloning(volumeInfo.getId(), "cloneOfSnapshot"); + long csTemplateId = getCsIdForCloning(volumeInfo.getId(), "cloneOfTemplate"); + + SolidFireUtil.SolidFireVolume sfVolume; + + if (csSnapshotId > 0) { + // We are supposed to create a clone of the underlying volume or snapshot that supports the CloudStack snapshot. + sfVolume = createClone(sfConnection, csSnapshotId, volumeInfo, sfAccountId, storagePoolId, DataObjectType.SNAPSHOT); + } else if (csTemplateId > 0) { + // Clone from template. + sfVolume = createClone(sfConnection, csTemplateId, volumeInfo, sfAccountId, storagePoolId, DataObjectType.TEMPLATE); + + long volumeSize = getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeInfo, _storagePoolDao.findById(storagePoolId)); + + if (volumeSize > sfVolume.getTotalSize()) { + // Expand the volume to include HSR. + SolidFireUtil.modifySolidFireVolume(sfConnection, sfVolume.getId(), volumeSize, getVolumeAttributes(volumeInfo), + sfVolume.getMinIops(), sfVolume.getMaxIops(), sfVolume.getBurstIops()); + + // Get the SolidFire volume from the SAN again because we just updated its size. + sfVolume = SolidFireUtil.getSolidFireVolume(sfConnection, sfVolume.getId()); + } + } + else { + sfVolume = createSolidFireVolume(sfConnection, volumeInfo, sfAccountId); + } + + String iqn = sfVolume.getIqn(); + + VolumeVO volume = _volumeDao.findById(volumeInfo.getId()); + + volume.set_iScsiName(iqn); + volume.setFolder(String.valueOf(sfVolume.getId())); + volume.setPoolType(StoragePoolType.IscsiLUN); + volume.setPoolId(storagePoolId); + + _volumeDao.update(volume.getId(), volume); + + updateVolumeDetails(volume.getId(), sfVolume.getTotalSize()); + + StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId); + + long capacityBytes = storagePool.getCapacityBytes(); + // getUsedBytes(StoragePool) will include the bytes of the newly created volume because + // updateVolumeDetails(long, long) has already been called for this volume + long usedBytes = getUsedBytes(storagePool); + + storagePool.setUsedBytes(usedBytes > capacityBytes ? capacityBytes : usedBytes); + + _storagePoolDao.update(storagePoolId, storagePool); + + return iqn; + } + + private void createTempVolume(SnapshotInfo snapshotInfo, long storagePoolId) { + long csSnapshotId = snapshotInfo.getId(); + + SnapshotDetailsVO snapshotDetails = _snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.SNAPSHOT_ID); + + if (snapshotDetails == null || snapshotDetails.getValue() == null) { + throw new CloudRuntimeException("'createTempVolume(SnapshotInfo, long)' should not be invoked unless " + SolidFireUtil.SNAPSHOT_ID + " exists."); + } + + SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, _storagePoolDetailsDao); + + snapshotDetails = _snapshotDetailsDao.findDetail(csSnapshotId, "tempVolume"); + + if (snapshotDetails != null && snapshotDetails.getValue() != null && snapshotDetails.getValue().equalsIgnoreCase("create")) { + long sfAccountId = getCreateSolidFireAccountId(sfConnection, snapshotInfo.getAccountId(), storagePoolId); + + SolidFireUtil.SolidFireVolume sfVolume = createCloneFromSnapshot(sfConnection, csSnapshotId, sfAccountId); + + addTempVolumeId(csSnapshotId, String.valueOf(sfVolume.getId())); + + handleSnapshotDetails(csSnapshotId, DiskTO.IQN, sfVolume.getIqn()); + } + else if (snapshotDetails != null && snapshotDetails.getValue() != null && snapshotDetails.getValue().equalsIgnoreCase("delete")) { + snapshotDetails = _snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.VOLUME_ID); + + SolidFireUtil.deleteSolidFireVolume(sfConnection, Long.parseLong(snapshotDetails.getValue())); + + removeTempVolumeId(csSnapshotId); + + snapshotDetails = _snapshotDetailsDao.findDetail(csSnapshotId, DiskTO.IQN); + + _snapshotDetailsDao.remove(snapshotDetails.getId()); + } + else { + throw new CloudRuntimeException("Invalid state in 'createTempVolume(SnapshotInfo, long)'"); + } + } + + private String createTemplateVolume(TemplateInfo templateInfo, long storagePoolId) { + verifySufficientBytesForStoragePool(templateInfo, storagePoolId); + + SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, _storagePoolDetailsDao); + + long sfAccountId = getCreateSolidFireAccountId(sfConnection, templateInfo.getAccountId(), storagePoolId); + + SolidFireUtil.SolidFireVolume sfVolume = createSolidFireVolume(sfConnection, templateInfo, sfAccountId); + + String iqn = sfVolume.getIqn(); + + VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(storagePoolId, templateInfo.getId()); + + templatePoolRef.setInstallPath(iqn); + templatePoolRef.setLocalDownloadPath(Long.toString(sfVolume.getId())); + templatePoolRef.setTemplateSize(sfVolume.getTotalSize()); + + _tmpltPoolDao.update(templatePoolRef.getId(), templatePoolRef); + + StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId); + + long capacityBytes = storagePool.getCapacityBytes(); + // getUsedBytes(StoragePool) will include the bytes of the newly created template volume because + // _tmpltPoolDao.update(Long, VMTemplateStoragePoolVO) has already been invoked + long usedBytes = getUsedBytes(storagePool); + + storagePool.setUsedBytes(usedBytes > capacityBytes ? capacityBytes : usedBytes); + + _storagePoolDao.update(storagePoolId, storagePool); + + return iqn; + } + + private void deleteVolume(VolumeInfo volumeInfo, long storagePoolId) { + try { + long volumeId = volumeInfo.getId(); + + SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, _storagePoolDetailsDao); + + deleteSolidFireVolume(sfConnection, volumeInfo); + + _volumeDetailsDao.removeDetails(volumeId); + + StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId); + + long usedBytes = getUsedBytes(storagePool, volumeId); + + storagePool.setUsedBytes(usedBytes < 0 ? 0 : usedBytes); + + _storagePoolDao.update(storagePoolId, storagePool); + } + catch (Exception ex) { --- End diff -- needed here? and why?
--- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---