You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mt...@apache.org on 2014/01/09 22:45:22 UTC
git commit: updated refs/heads/master to 03118c2
Updated Branches:
refs/heads/master 09da5153d -> 03118c296
Merge from 4.3: CLOUDSTACK-4810: Enable hypervisor snapshots for CloudStack-managed storage (for XenServer and VMware)
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/03118c29
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/03118c29
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/03118c29
Branch: refs/heads/master
Commit: 03118c2969d145bdade7f685ee580c37124187c8
Parents: 09da515
Author: Mike Tutkowski <mi...@solidfire.com>
Authored: Thu Jan 9 14:42:35 2014 -0700
Committer: Mike Tutkowski <mi...@solidfire.com>
Committed: Thu Jan 9 14:44:35 2014 -0700
----------------------------------------------------------------------
api/src/com/cloud/storage/Volume.java | 2 -
.../api/storage/PrimaryDataStoreDriver.java | 5 ++
.../orchestration/VolumeOrchestrator.java | 7 +--
.../schema/src/com/cloud/storage/VolumeVO.java | 1 -
.../test/FakePrimaryDataStoreDriver.java | 7 +++
.../cloudstack/storage/volume/VolumeObject.java | 1 -
.../CloudStackPrimaryDataStoreDriverImpl.java | 6 +++
.../SamplePrimaryDataStoreDriverImpl.java | 7 +++
.../driver/SolidfirePrimaryDataStoreDriver.java | 57 ++++++++++++--------
.../storage/datastore/util/SolidFireUtil.java | 48 +++++++++++++----
.../com/cloud/capacity/CapacityManagerImpl.java | 15 ++++--
.../com/cloud/storage/StorageManagerImpl.java | 17 +++++-
12 files changed, 129 insertions(+), 44 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03118c29/api/src/com/cloud/storage/Volume.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/Volume.java
index bb5ee08..84f0872 100755
--- a/api/src/com/cloud/storage/Volume.java
+++ b/api/src/com/cloud/storage/Volume.java
@@ -189,7 +189,5 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba
Long getVmSnapshotChainSize();
- void setHypervisorSnapshotReserve(Integer hypervisorSnapshotReserve);
-
Integer getHypervisorSnapshotReserve();
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03118c29/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java
index f3399cd..369ee9c 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java
@@ -21,9 +21,14 @@ package org.apache.cloudstack.engine.subsystem.api.storage;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.storage.command.CommandResult;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.Volume;
+
public interface PrimaryDataStoreDriver extends DataStoreDriver {
public ChapInfo getChapInfo(VolumeInfo volumeInfo);
+ public long getVolumeSizeIncludingHypervisorSnapshotReserve(Volume volume, StoragePool pool);
+
public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCmdResult> callback);
public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CommandResult> callback);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03118c29/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
index 72aaf3d..f094fb2 100644
--- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
@@ -404,6 +404,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
@DB
public VolumeInfo createVolume(VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate template, DataCenter dc, Pod pod, Long clusterId, ServiceOffering offering,
DiskOffering diskOffering, List<StoragePool> avoids, long size, HypervisorType hyperType) {
+ volume = updateHypervisorSnapshotReserveForVolume(diskOffering, volume, hyperType);
+
StoragePool pool = null;
DiskProfile dskCh = null;
@@ -423,8 +425,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
pool = findStoragePool(dskCh, dc, pod, clusterId, vm.getHostId(), vm, avoidPools);
if (pool == null) {
- s_logger.warn("Unable to find storage pool when create volume " + volume.getName());
- throw new CloudRuntimeException("Unable to find storage pool when create volume" + volume.getName());
+ s_logger.warn("Unable to find suitable primary storage when creating volume " + volume.getName());
+ throw new CloudRuntimeException("Unable to find suitable primary storage when creating volume " + volume.getName());
}
if (s_logger.isDebugEnabled()) {
@@ -436,7 +438,6 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
AsyncCallFuture<VolumeApiResult> future = null;
boolean isNotCreatedFromTemplate = volume.getTemplateId() == null ? true : false;
if (isNotCreatedFromTemplate) {
- volume = updateHypervisorSnapshotReserveForVolume(diskOffering, volume, hyperType);
future = volService.createVolumeAsync(volume, store);
} else {
TemplateInfo templ = tmplFactory.getTemplate(template.getId(), DataStoreRole.Image);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03118c29/engine/schema/src/com/cloud/storage/VolumeVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/VolumeVO.java b/engine/schema/src/com/cloud/storage/VolumeVO.java
index 944847f..901e07c 100755
--- a/engine/schema/src/com/cloud/storage/VolumeVO.java
+++ b/engine/schema/src/com/cloud/storage/VolumeVO.java
@@ -587,7 +587,6 @@ public class VolumeVO implements Volume {
this.state = state;
}
- @Override
public void setHypervisorSnapshotReserve(Integer hypervisorSnapshotReserve) {
this.hypervisorSnapshotReserve = hypervisorSnapshotReserve;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03118c29/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakePrimaryDataStoreDriver.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakePrimaryDataStoreDriver.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakePrimaryDataStoreDriver.java
index 54dbb65..dad6408 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakePrimaryDataStoreDriver.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakePrimaryDataStoreDriver.java
@@ -36,6 +36,8 @@ import org.apache.cloudstack.storage.to.SnapshotObjectTO;
import com.cloud.agent.api.to.DataStoreTO;
import com.cloud.agent.api.to.DataTO;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.Volume;
public class FakePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
boolean snapshotResult = true;
@@ -46,6 +48,11 @@ public class FakePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
}
@Override
+ public long getVolumeSizeIncludingHypervisorSnapshotReserve(Volume volume, StoragePool pool) {
+ return volume.getSize();
+ }
+
+ @Override
public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCmdResult> callback) {
CreateCmdResult result = new CreateCmdResult(null, null);
if (snapshotResult) {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03118c29/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
index 76a94cd..fd0f2c1 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
@@ -153,7 +153,6 @@ public class VolumeObject implements VolumeInfo {
return volumeVO.getMaxIops();
}
- @Override
public void setHypervisorSnapshotReserve(Integer hypervisorSnapshotReserve) {
volumeVO.setHypervisorSnapshotReserve(hypervisorSnapshotReserve);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03118c29/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java
index bab960e..c8e2582 100644
--- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java
+++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java
@@ -68,6 +68,7 @@ import com.cloud.storage.ResizeVolumePayload;
import com.cloud.storage.Storage;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePool;
+import com.cloud.storage.Volume;
import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.VMTemplateDao;
@@ -149,6 +150,11 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri
}
@Override
+ public long getVolumeSizeIncludingHypervisorSnapshotReserve(Volume volume, StoragePool pool) {
+ return volume.getSize();
+ }
+
+ @Override
public void createAsync(DataStore dataStore, DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
String errMsg = null;
Answer answer = null;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03118c29/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java
index 5e5a934..4cfc097 100644
--- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java
+++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java
@@ -42,6 +42,8 @@ import org.apache.cloudstack.storage.datastore.DataObjectManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.to.DataStoreTO;
import com.cloud.agent.api.to.DataTO;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.Volume;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.utils.exception.CloudRuntimeException;
@@ -78,6 +80,11 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
return null;
}
+ @Override
+ public long getVolumeSizeIncludingHypervisorSnapshotReserve(Volume volume, StoragePool pool) {
+ return volume.getSize();
+ }
+
private class CreateVolumeContext<T> extends AsyncRpcContext<T> {
private final DataObject volume;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03118c29/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
index d85ed0d..460cb0d 100644
--- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
+++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
@@ -46,6 +46,8 @@ import com.cloud.agent.api.to.DataStoreTO;
import com.cloud.agent.api.to.DataTO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.Volume;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.dao.VolumeDetailsDao;
@@ -284,8 +286,20 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
iops = new Iops(volumeInfo.getMinIops(), volumeInfo.getMaxIops(), getDefaultBurstIops(storagePoolId, volumeInfo.getMaxIops()));
}
- long volumeSize = volumeInfo.getSize();
- Integer hypervisorSnapshotReserve = volumeInfo.getHypervisorSnapshotReserve();
+ long volumeSize = getVolumeSizeIncludingHypervisorSnapshotReserve(volumeInfo, _storagePoolDao.findById(storagePoolId));
+
+ long sfVolumeId = SolidFireUtil.createSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword,
+ getSolidFireVolumeName(volumeInfo.getName()), sfAccountId, volumeSize, true,
+ NumberFormat.getInstance().format(volumeInfo.getSize()),
+ iops.getMinIops(), iops.getMaxIops(), iops.getBurstIops());
+
+ return SolidFireUtil.getSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfVolumeId);
+ }
+
+ @Override
+ public long getVolumeSizeIncludingHypervisorSnapshotReserve(Volume volume, StoragePool pool) {
+ long volumeSize = volume.getSize();
+ Integer hypervisorSnapshotReserve = volume.getHypervisorSnapshotReserve();
if (hypervisorSnapshotReserve != null) {
if (hypervisorSnapshotReserve < 25) {
@@ -295,11 +309,7 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
volumeSize += volumeSize * (hypervisorSnapshotReserve / 100f);
}
- long sfVolumeId =
- SolidFireUtil.createSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword, getSolidFireVolumeName(volumeInfo.getName()), sfAccountId,
- volumeSize, true, NumberFormat.getNumberInstance().format(volumeInfo.getSize().toString()), iops.getMinIops(), iops.getMaxIops(), iops.getBurstIops());
-
- return SolidFireUtil.getSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfVolumeId);
+ return volumeSize;
}
private String getSolidFireVolumeName(String strCloudStackVolumeName) {
@@ -356,11 +366,12 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
}
}
- private void deleteSolidFireVolume(VolumeInfo volumeInfo, SolidFireConnection sfConnection) {
+ private SolidFireUtil.SolidFireVolume deleteSolidFireVolume(VolumeInfo volumeInfo, SolidFireConnection sfConnection)
+ {
Long storagePoolId = volumeInfo.getPoolId();
if (storagePoolId == null) {
- return; // this volume was never assigned to a storage pool, so no SAN volume should exist for it
+ return null; // this volume was never assigned to a storage pool, so no SAN volume should exist for it
}
String mVip = sfConnection.getManagementVip();
@@ -370,7 +381,7 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
long sfVolumeId = Long.parseLong(volumeInfo.getFolder());
- SolidFireUtil.deleteSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfVolumeId);
+ return SolidFireUtil.deleteSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfVolumeId);
}
private String getSfAccountName(String csAccountUuid, long csAccountId) {
@@ -429,7 +440,7 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
long capacityBytes = storagePool.getCapacityBytes();
long usedBytes = storagePool.getUsedBytes();
- usedBytes += volumeInfo.getSize();
+ usedBytes += sfVolume.getTotalSize();
storagePool.setUsedBytes(usedBytes > capacityBytes ? capacityBytes : usedBytes);
@@ -493,31 +504,31 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
if (dataObject.getType() == DataObjectType.VOLUME) {
VolumeInfo volumeInfo = (VolumeInfo)dataObject;
- AccountVO account = _accountDao.findById(volumeInfo.getAccountId());
- AccountDetailVO accountDetails = _accountDetailsDao.findDetail(account.getAccountId(), SolidFireUtil.ACCOUNT_ID);
- long sfAccountId = Long.parseLong(accountDetails.getValue());
+ // AccountVO account = _accountDao.findById(volumeInfo.getAccountId());
+ // AccountDetailVO accountDetails = _accountDetailsDao.findDetail(account.getAccountId(), SolidFireUtil.ACCOUNT_ID);
+ // long sfAccountId = Long.parseLong(accountDetails.getValue());
long storagePoolId = dataStore.getId();
SolidFireConnection sfConnection = getSolidFireConnection(storagePoolId);
- deleteSolidFireVolume(volumeInfo, sfConnection);
+ SolidFireUtil.SolidFireVolume sfVolume = deleteSolidFireVolume(volumeInfo, sfConnection);
_volumeDao.deleteVolumesByInstance(volumeInfo.getId());
- // if (!sfAccountHasVolume(sfAccountId, sfConnection)) {
- // // delete the account from the SolidFire SAN
- // deleteSolidFireAccount(sfAccountId, sfConnection);
+ // if (!sfAccountHasVolume(sfAccountId, sfConnection)) {
+ // // delete the account from the SolidFire SAN
+ // deleteSolidFireAccount(sfAccountId, sfConnection);
//
- // // delete the info in the account_details table
- // // that's related to the SolidFire account
- // _accountDetailsDao.deleteDetails(account.getAccountId());
- // }
+ // // delete the info in the account_details table
+ // // that's related to the SolidFire account
+ // _accountDetailsDao.deleteDetails(account.getAccountId());
+ // }
StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);
long usedBytes = storagePool.getUsedBytes();
- usedBytes -= volumeInfo.getSize();
+ usedBytes -= sfVolume != null ? sfVolume.getTotalSize() : 0;
storagePool.setUsedBytes(usedBytes < 0 ? 0 : usedBytes);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03118c29/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java
index 5f26c97..131e088 100644
--- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java
+++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java
@@ -95,7 +95,10 @@ public class SolidFireUtil {
return volumeCreateResult.result.volumeID;
}
- public static void deleteSolidFireVolume(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lVolumeId) {
+ public static SolidFireVolume deleteSolidFireVolume(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lVolumeId)
+ {
+ SolidFireVolume sfVolume = getSolidFireVolume(strSfMvip, iSfPort, strSfAdmin, strSfPassword, lVolumeId);
+
final Gson gson = new GsonBuilder().create();
VolumeToDelete volumeToDelete = new VolumeToDelete(lVolumeId);
@@ -103,6 +106,8 @@ public class SolidFireUtil {
String strVolumeToDeleteJson = gson.toJson(volumeToDelete);
executeJsonRpc(strVolumeToDeleteJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword);
+
+ return sfVolume;
}
public static void purgeSolidFireVolume(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lVolumeId) {
@@ -132,8 +137,9 @@ public class SolidFireUtil {
String strVolumeIqn = getVolumeIqn(volumeGetResult, lVolumeId);
long lAccountId = getVolumeAccountId(volumeGetResult, lVolumeId);
String strVolumeStatus = getVolumeStatus(volumeGetResult, lVolumeId);
+ long lTotalSize = getVolumeTotalSize(volumeGetResult, lVolumeId);
- return new SolidFireVolume(lVolumeId, strVolumeName, strVolumeIqn, lAccountId, strVolumeStatus);
+ return new SolidFireVolume(lVolumeId, strVolumeName, strVolumeIqn, lAccountId, strVolumeStatus, lTotalSize);
}
public static List<SolidFireVolume> getSolidFireVolumesForAccountId(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lAccountId) {
@@ -152,7 +158,7 @@ public class SolidFireUtil {
List<SolidFireVolume> sfVolumes = new ArrayList<SolidFireVolume>();
for (VolumeGetResult.Result.Volume volume : volumeGetResult.result.volumes) {
- sfVolumes.add(new SolidFireVolume(volume.volumeID, volume.name, volume.iqn, volume.accountID, volume.status));
+ sfVolumes.add(new SolidFireVolume(volume.volumeID, volume.name, volume.iqn, volume.accountID, volume.status, volume.totalSize));
}
return sfVolumes;
@@ -166,13 +172,17 @@ public class SolidFireUtil {
private final String _iqn;
private final long _accountId;
private final String _status;
+ private final long _totalSize;
- public SolidFireVolume(long id, String name, String iqn, long accountId, String status) {
+ public SolidFireVolume(long id, String name, String iqn,
+ long accountId, String status, long totalSize)
+ {
_id = id;
_name = name;
_iqn = "/" + iqn + "/0";
_accountId = accountId;
_status = status;
+ _totalSize = totalSize;
}
public long getId() {
@@ -195,6 +205,10 @@ public class SolidFireUtil {
return ACTIVE.equalsIgnoreCase(_status);
}
+ public long getTotalSize() {
+ return _totalSize;
+ }
+
@Override
public int hashCode() {
return _iqn.hashCode();
@@ -217,7 +231,9 @@ public class SolidFireUtil {
SolidFireVolume sfv = (SolidFireVolume)obj;
- if (_id == sfv._id && _name.equals(sfv._name) && _iqn.equals(sfv._iqn) && _accountId == sfv._accountId && isActive() == sfv.isActive()) {
+ if (_id == sfv._id && _name.equals(sfv._name) &&
+ _iqn.equals(sfv._iqn) && _accountId == sfv._accountId &&
+ isActive() == sfv.isActive() && getTotalSize() == sfv.getTotalSize()) {
return true;
}
@@ -366,7 +382,7 @@ public class SolidFireUtil {
List<SolidFireVolume> deletedVolumes = new ArrayList<SolidFireVolume>();
for (VolumeGetResult.Result.Volume volume : volumeGetResult.result.volumes) {
- deletedVolumes.add(new SolidFireVolume(volume.volumeID, volume.name, volume.iqn, volume.accountID, volume.status));
+ deletedVolumes.add(new SolidFireVolume(volume.volumeID, volume.name, volume.iqn, volume.accountID, volume.status, volume.totalSize));
}
return deletedVolumes;
@@ -655,6 +671,7 @@ public class SolidFireUtil {
private String iqn;
private long accountID;
private String status;
+ private long totalSize;
}
}
}
@@ -811,7 +828,7 @@ public class SolidFireUtil {
return volumeGetResult.result.volumes[0].name;
}
- throw new CloudRuntimeException("Could not determine the name of the volume, " + "but the volume was created with an ID of " + lVolumeId + ".");
+ throw new CloudRuntimeException("Could not determine the name of the volume for volume ID of " + lVolumeId + ".");
}
private static String getVolumeIqn(VolumeGetResult volumeGetResult, long lVolumeId) {
@@ -819,7 +836,7 @@ public class SolidFireUtil {
return volumeGetResult.result.volumes[0].iqn;
}
- throw new CloudRuntimeException("Could not determine the IQN of the volume, " + "but the volume was created with an ID of " + lVolumeId + ".");
+ throw new CloudRuntimeException("Could not determine the IQN of the volume for volume ID of " + lVolumeId + ".");
}
private static long getVolumeAccountId(VolumeGetResult volumeGetResult, long lVolumeId) {
@@ -827,7 +844,7 @@ public class SolidFireUtil {
return volumeGetResult.result.volumes[0].accountID;
}
- throw new CloudRuntimeException("Could not determine the volume's account ID, " + "but the volume was created with an ID of " + lVolumeId + ".");
+ throw new CloudRuntimeException("Could not determine the account ID of the volume for volume ID of " + lVolumeId + ".");
}
private static String getVolumeStatus(VolumeGetResult volumeGetResult, long lVolumeId) {
@@ -835,6 +852,17 @@ public class SolidFireUtil {
return volumeGetResult.result.volumes[0].status;
}
- throw new CloudRuntimeException("Could not determine the status of the volume, " + "but the volume was created with an ID of " + lVolumeId + ".");
+ throw new CloudRuntimeException("Could not determine the status of the volume for volume ID of " + lVolumeId + ".");
+ }
+
+ private static long getVolumeTotalSize(VolumeGetResult volumeGetResult, long lVolumeId)
+ {
+ if (volumeGetResult.result.volumes != null && volumeGetResult.result.volumes.length == 1 &&
+ volumeGetResult.result.volumes[0].volumeID == lVolumeId)
+ {
+ return volumeGetResult.result.volumes[0].totalSize;
+ }
+
+ throw new CloudRuntimeException("Could not determine the total size of the volume for volume ID of " + lVolumeId + ".");
}
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03118c29/server/src/com/cloud/capacity/CapacityManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/capacity/CapacityManagerImpl.java b/server/src/com/cloud/capacity/CapacityManagerImpl.java
index 7daf277..024c7f2 100755
--- a/server/src/com/cloud/capacity/CapacityManagerImpl.java
+++ b/server/src/com/cloud/capacity/CapacityManagerImpl.java
@@ -500,10 +500,19 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
@Override
public long getAllocatedPoolCapacity(StoragePoolVO pool, VMTemplateVO templateForVmCreation) {
+ long totalAllocatedSize = 0;
- // Get size for all the non-destroyed volumes
- Pair<Long, Long> sizes = _volumeDao.getNonDestroyedCountAndTotalByPool(pool.getId());
- long totalAllocatedSize = sizes.second() + sizes.first() * _extraBytesPerVolume;
+ // if the storage pool is managed, the used bytes can be larger than the sum of the sizes of all of the non-destroyed volumes
+ // in this case, just get the used bytes from the storage pool object
+ if (pool.isManaged()) {
+ totalAllocatedSize = pool.getUsedBytes();
+ }
+ else {
+ // Get size for all the non-destroyed volumes
+ Pair<Long, Long> sizes = _volumeDao.getNonDestroyedCountAndTotalByPool(pool.getId());
+
+ totalAllocatedSize = sizes.second() + sizes.first() * _extraBytesPerVolume;
+ }
// Get size for VM Snapshots
totalAllocatedSize = totalAllocatedSize + _volumeDao.getVMSnapshotSizeByPool(pool.getId());
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03118c29/server/src/com/cloud/storage/StorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java
index 9afd47a..c274e2c 100755
--- a/server/src/com/cloud/storage/StorageManagerImpl.java
+++ b/server/src/com/cloud/storage/StorageManagerImpl.java
@@ -54,6 +54,7 @@ import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
@@ -62,6 +63,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
@@ -1542,7 +1544,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
}
}
if (volume.getState() != Volume.State.Ready) {
- totalAskingSize = totalAskingSize + volume.getSize();
+ totalAskingSize = totalAskingSize + getVolumeSizeIncludingHvSsReserve(volume, pool);
}
}
@@ -1581,6 +1583,19 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
return true;
}
+ private long getVolumeSizeIncludingHvSsReserve(Volume volume, StoragePool pool) {
+ DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
+ DataStoreDriver storeDriver = storeProvider.getDataStoreDriver();
+
+ if (storeDriver instanceof PrimaryDataStoreDriver) {
+ PrimaryDataStoreDriver primaryStoreDriver = (PrimaryDataStoreDriver)storeDriver;
+
+ return primaryStoreDriver.getVolumeSizeIncludingHypervisorSnapshotReserve(volume, pool);
+ }
+
+ return volume.getSize();
+ }
+
@Override
public void createCapacityEntry(long poolId) {
StoragePoolVO storage = _storagePoolDao.findById(poolId);