Updated Branches:
  refs/heads/4.3 cd11d3e9d -> bb8794203

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/bb879420
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/bb879420
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/bb879420

Branch: refs/heads/4.3
Commit: bb8794203e6a961da0f9cf755bd0ada89c49a2d8
Parents: cd11d3e
Author: Mike Tutkowski <[email protected]>
Authored: Tue Nov 12 12:08:03 2013 -0700
Committer: Mike Tutkowski <[email protected]>
Committed: Tue Nov 12 16:52:12 2013 -0700

----------------------------------------------------------------------
 api/src/com/cloud/storage/Volume.java           |  2 -
 .../api/storage/PrimaryDataStoreDriver.java     |  4 ++
 .../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   | 47 +++++++++++-----
 .../com/cloud/capacity/CapacityManagerImpl.java | 17 ++++--
 .../com/cloud/storage/StorageManagerImpl.java   | 17 +++++-
 12 files changed, 124 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb879420/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 dd59f12..b1a253f 100755
--- a/api/src/com/cloud/storage/Volume.java
+++ b/api/src/com/cloud/storage/Volume.java
@@ -186,7 +186,5 @@ public interface Volume extends ControlledEntity, Identity, 
InternalIdentity, Ba
        Storage.ImageFormat getFormat();
        Long getVmSnapshotChainSize();
 
-    void setHypervisorSnapshotReserve(Integer hypervisorSnapshotReserve);
-
     Integer getHypervisorSnapshotReserve();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb879420/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 b124d83..6c353d9 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,8 +21,12 @@ 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/bb879420/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 f839d6c..71e8b7d 100644
--- 
a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
+++ 
b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
@@ -374,6 +374,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;
 
         if (diskOffering != null && diskOffering.isCustomized()) {
@@ -393,8 +395,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()) {
@@ -406,7 +408,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/bb879420/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 a130d89..e3516a3 100755
--- a/engine/schema/src/com/cloud/storage/VolumeVO.java
+++ b/engine/schema/src/com/cloud/storage/VolumeVO.java
@@ -587,6 +587,7 @@ public class VolumeVO implements Volume {
         this.hypervisorSnapshotReserve = hypervisorSnapshotReserve;
     }
 
+    @Override
     public Integer getHypervisorSnapshotReserve() {
         return hypervisorSnapshotReserve;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb879420/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 de64b8f..72373e2 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
@@ -35,6 +35,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;
@@ -44,6 +46,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/bb879420/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 f761a0c..859427c 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
@@ -141,7 +141,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/bb879420/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 327d87c..9da29d6 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
@@ -23,6 +23,7 @@ import java.util.UUID;
 import javax.inject.Inject;
 
 import com.cloud.storage.*;
+
 import org.apache.cloudstack.storage.to.SnapshotObjectTO;
 import org.apache.log4j.Logger;
 
@@ -133,6 +134,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/bb879420/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 8f4c7bb..302cb09 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
@@ -40,6 +40,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;
 
@@ -71,6 +73,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;
         public CreateVolumeContext(AsyncCompletionCallback<T> callback, 
DataObject volume) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bb879420/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 1c726cd..8a98b62 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
@@ -44,6 +44,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;
@@ -288,8 +290,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) {
@@ -299,12 +313,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) {
@@ -367,12 +376,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();
@@ -382,7 +391,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) {
@@ -443,7 +452,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);
 
@@ -510,31 +519,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/bb879420/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 6659f98..1bf3788 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
@@ -97,8 +97,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);
@@ -106,6 +108,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)
@@ -137,8 +141,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,
@@ -160,7 +165,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;
@@ -175,15 +180,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)
+                long accountId, String status, long totalSize)
         {
             _id = id;
             _name = name;
             _iqn = "/" + iqn + "/0";
             _accountId = accountId;
             _status = status;
+            _totalSize = totalSize;
         }
 
         public long getId()
@@ -211,6 +218,10 @@ public class SolidFireUtil
             return ACTIVE.equalsIgnoreCase(_status);
         }
 
+        public long getTotalSize() {
+            return _totalSize;
+        }
+
         @Override
         public int hashCode() {
             return _iqn.hashCode();
@@ -235,7 +246,7 @@ public class SolidFireUtil
 
             if (_id == sfv._id && _name.equals(sfv._name) &&
                 _iqn.equals(sfv._iqn) && _accountId == sfv._accountId &&
-                isActive() == sfv.isActive()) {
+                isActive() == sfv.isActive() && getTotalSize() == 
sfv.getTotalSize()) {
                 return true;
             }
 
@@ -402,7 +413,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;
@@ -748,6 +759,7 @@ public class SolidFireUtil
                 private String iqn;
                 private long accountID;
                 private String status;
+                private long totalSize;
             }
         }
     }
@@ -927,8 +939,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)
@@ -939,8 +950,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)
@@ -951,8 +961,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)
@@ -963,7 +972,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/bb879420/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 70491bc..52cab12 100755
--- a/server/src/com/cloud/capacity/CapacityManagerImpl.java
+++ b/server/src/com/cloud/capacity/CapacityManagerImpl.java
@@ -475,11 +475,20 @@ public class CapacityManagerImpl extends ManagerBase 
implements CapacityManager,
     }
 
     @Override
-    public long getAllocatedPoolCapacity(StoragePoolVO pool, VMTemplateVO 
templateForVmCreation){
+    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/bb879420/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 e42d871..e81e30e 100755
--- a/server/src/com/cloud/storage/StorageManagerImpl.java
+++ b/server/src/com/cloud/storage/StorageManagerImpl.java
@@ -55,6 +55,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;
@@ -63,6 +64,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;
@@ -1582,7 +1584,7 @@ public class StorageManagerImpl extends ManagerBase 
implements StorageManager, C
                 }
             }
             if (volume.getState() != Volume.State.Ready) {
-                totalAskingSize = totalAskingSize + volume.getSize();
+                totalAskingSize = totalAskingSize + 
getVolumeSizeIncludingHvSsReserve(volume, pool);
             }
         }
 
@@ -1623,6 +1625,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);

Reply via email to