Update to volume-resize logic

Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/3773ff06
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/3773ff06
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/3773ff06

Branch: refs/heads/saml2
Commit: 3773ff060e994d665b3b6d37f79df40c19a74c26
Parents: 1436ce6
Author: Mike Tutkowski <mike.tutkow...@solidfire.com>
Authored: Thu Aug 21 14:47:40 2014 -0600
Committer: Mike Tutkowski <mike.tutkow...@solidfire.com>
Committed: Thu Aug 21 20:18:20 2014 -0600

----------------------------------------------------------------------
 .../xenserver/resource/CitrixResourceBase.java  |  3 +-
 .../driver/SolidFirePrimaryDataStoreDriver.java |  4 +-
 ...olidFireSharedPrimaryDataStoreLifeCycle.java |  2 +-
 .../storage/datastore/util/SolidFireUtil.java   | 60 +++++++++++++++++++-
 .../com/cloud/storage/VolumeApiServiceImpl.java | 49 ++++++++++++----
 5 files changed, 98 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3773ff06/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
 
b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
index e391b3e..3ba8271 100644
--- 
a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
+++ 
b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
@@ -1928,7 +1928,6 @@ public abstract class CitrixResourceBase implements 
ServerResource, HypervisorRe
         Long volumeSize = Long.parseLong(details.get(DiskTO.VOLUME_SIZE));
 
         if (vdi == null) {
-
             vdi = createVdi(sr, vdiNameLabel, volumeSize);
         } else {
             // if VDI is not null, it must have already been created, so check 
whether a resize of the volume was performed
@@ -1939,7 +1938,7 @@ public abstract class CitrixResourceBase implements 
ServerResource, HypervisorRe
             long vdiVirtualSize = vdi.getVirtualSize(conn);
 
             if (vdiVirtualSize != volumeSize) {
-                s_logger.info("resizing the datadisk(vdi) from vdiVirtualsize 
:"+ vdiVirtualSize + "to volumeSize :" + volumeSize);
+                s_logger.info("resizing the data disk (vdi) from 
vdiVirtualsize: "+ vdiVirtualSize + " to volumeSize: " + volumeSize);
 
                 try {
                     vdi.resize(conn, volumeSize);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3773ff06/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 2228c59..6eee9fe 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
@@ -420,8 +420,8 @@ public class SolidFirePrimaryDataStoreDriver implements 
PrimaryDataStoreDriver {
 
             verifySufficientIopsForStoragePool(storagePoolId, 
volumeInfo.getId(), payload.newMinIops);
 
-            SolidFireUtil.modifySolidFireVolume(sfConnection, sfVolumeId, 
sfVolume.getTotalSize(), payload.newMinIops, payload.newMaxIops,
-                    getDefaultBurstIops(storagePoolId, payload.newMaxIops));
+            SolidFireUtil.modifySolidFireVolume(sfConnection, sfVolumeId, 
sfVolume.getTotalSize(), NumberFormat.getInstance().format(payload.newSize),
+                    payload.newMinIops, payload.newMaxIops, 
getDefaultBurstIops(storagePoolId, payload.newMaxIops));
 
             VolumeVO volume = _volumeDao.findById(volumeInfo.getId());
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3773ff06/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java
----------------------------------------------------------------------
diff --git 
a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java
 
b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java
index 5065822..30d6659 100644
--- 
a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java
+++ 
b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java
@@ -621,7 +621,7 @@ public class SolidFireSharedPrimaryDataStoreLifeCycle 
implements PrimaryDataStor
             }
         }
 
-        SolidFireUtil.modifySolidFireVolume(sfConnection, 
getVolumeId(storagePool.getId()), size, minIops, maxIops, burstIops);
+        SolidFireUtil.modifySolidFireVolume(sfConnection, 
getVolumeId(storagePool.getId()), size, null, minIops, maxIops, burstIops);
 
         SolidFireUtil.updateCsDbWithSolidFireIopsInfo(storagePool.getId(), 
_primaryDataStoreDao, _storagePoolDetailsDao, minIops, maxIops, burstIops);
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3773ff06/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 307ddbc..2aa8914 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
@@ -467,11 +467,14 @@ public class SolidFireUtil {
         return volumeCreateResult.result.volumeID;
     }
 
-    public static void modifySolidFireVolume(SolidFireConnection sfConnection, 
long volumeId, long totalSize, long minIops, long maxIops, long burstIops)
+    public static void modifySolidFireVolume(SolidFireConnection sfConnection, 
long volumeId, long totalSize, String strCloudStackVolumeSize,
+            long minIops, long maxIops, long burstIops)
     {
         final Gson gson = new GsonBuilder().create();
 
-        VolumeToModify volumeToModify = new VolumeToModify(volumeId, 
totalSize, minIops, maxIops, burstIops);
+        Object volumeToModify = strCloudStackVolumeSize != null && 
strCloudStackVolumeSize.trim().length() > 0 ?
+                new VolumeToModifyWithCloudStackVolumeSize(volumeId, 
totalSize, strCloudStackVolumeSize, minIops, maxIops, burstIops) :
+                new VolumeToModify(volumeId, totalSize, minIops, maxIops, 
burstIops);
 
         String strVolumeToModifyJson = gson.toJson(volumeToModify);
 
@@ -947,8 +950,8 @@ public class SolidFireUtil {
             private final long accountID;
             private final long totalSize;
             private final boolean enable512e;
-            private final VolumeToCreateParamsQoS qos;
             private final VolumeToCreateParamsAttributes attributes;
+            private final VolumeToCreateParamsQoS qos;
 
             private VolumeToCreateParams(final String strVolumeName, final 
long lAccountId, final long lTotalSize, final boolean bEnable512e,
                     final String strCloudStackVolumeSize, final long lMinIOPS, 
final long lMaxIOPS, final long lBurstIOPS) {
@@ -1025,6 +1028,57 @@ public class SolidFireUtil {
     }
 
     @SuppressWarnings("unused")
+    private static final class VolumeToModifyWithCloudStackVolumeSize
+    {
+        private final String method = "ModifyVolume";
+        private final VolumeToModifyParams params;
+
+        private VolumeToModifyWithCloudStackVolumeSize(final long lVolumeId, 
final long lTotalSize, final String strCloudStackVolumeSize,
+                final long lMinIOPS, final long lMaxIOPS, final long 
lBurstIOPS)
+        {
+            params = new VolumeToModifyParams(lVolumeId, lTotalSize, 
strCloudStackVolumeSize, lMinIOPS, lMaxIOPS, lBurstIOPS);
+        }
+
+        private static final class VolumeToModifyParams
+        {
+            private final long volumeID;
+            private final long totalSize;
+            private final VolumeToModifyParamsAttributes attributes;
+            private final VolumeToModifyParamsQoS qos;
+
+            private VolumeToModifyParams(final long lVolumeId, final long 
lTotalSize, String strCloudStackVolumeSize, final long lMinIOPS, final long 
lMaxIOPS, final long lBurstIOPS)
+            {
+                volumeID = lVolumeId;
+
+                totalSize = lTotalSize;
+
+                attributes = new 
VolumeToModifyParamsAttributes(strCloudStackVolumeSize);
+                qos = new VolumeToModifyParamsQoS(lMinIOPS, lMaxIOPS, 
lBurstIOPS);
+            }
+        }
+
+        private static final class VolumeToModifyParamsAttributes {
+            private final String CloudStackVolumeSize;
+
+            private VolumeToModifyParamsAttributes(final String 
strCloudStackVolumeSize) {
+                CloudStackVolumeSize = strCloudStackVolumeSize;
+            }
+        }
+
+        private static final class VolumeToModifyParamsQoS {
+            private final long minIOPS;
+            private final long maxIOPS;
+            private final long burstIOPS;
+
+            private VolumeToModifyParamsQoS(final long lMinIOPS, final long 
lMaxIOPS, final long lBurstIOPS) {
+                minIOPS = lMinIOPS;
+                maxIOPS = lMaxIOPS;
+                burstIOPS = lBurstIOPS;
+            }
+        }
+    }
+
+    @SuppressWarnings("unused")
     private static final class VolumeToModify
     {
         private final String method = "ModifyVolume";

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3773ff06/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java 
b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index 0734385..0c7c6e5 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -851,7 +851,7 @@ public class VolumeApiServiceImpl extends ManagerBase 
implements VolumeApiServic
             }
         }
 
-        // Note: The storage plug-in in question should perform validation on 
the IOPS to check if a sufficient number of IOPS are available to perform
+        // Note: The storage plug-in in question should perform validation on 
the IOPS to check if a sufficient number of IOPS is available to perform
         // the requested change
 
         /* If this volume has never been beyond allocated state, short circuit 
everything and simply update the database. */
@@ -970,9 +970,21 @@ public class VolumeApiServiceImpl extends ManagerBase 
implements VolumeApiServic
                 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.";
+
+            StoragePoolVO storagePool = 
_storagePoolDao.findById(volume.getPoolId());
+
+            if (storagePool.isManaged() && storagePool.getHypervisor() == 
HypervisorType.Any && hosts != null && hosts.length > 0) {
+                HostVO host = this._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("VM must be stopped 
or disk detached in order to resize with the Xen HV");
+                throw new InvalidParameterValueException(errorMsg);
             }
         }
 
@@ -982,8 +994,30 @@ public class VolumeApiServiceImpl extends ManagerBase 
implements VolumeApiServic
             VolumeInfo vol = volFactory.getVolume(volume.getId());
             vol.addPayload(payload);
 
+            StoragePoolVO storagePool = 
_storagePoolDao.findById(vol.getPoolId());
+
+            // managed storage is designed in such a way that the storage 
plug-in does not
+            // talk to the hypervisor layer; as such, if the storage is 
managed and the
+            // current and new sizes are different, then CloudStack (i.e. not 
a storage plug-in)
+            // 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);
+            }
+
+            // 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();
+
             if (result.isFailed()) {
                 s_logger.warn("Failed to resize the volume " + volume);
                 String details = "";
@@ -995,19 +1029,10 @@ public class VolumeApiServiceImpl extends ManagerBase 
implements VolumeApiServic
 
             volume = _volsDao.findById(volume.getId());
 
-            StoragePoolVO storagePool = 
_storagePoolDao.findById(vol.getPoolId());
-
-            if (currentSize != newSize && storagePool.isManaged()) {
-                if (hosts != null && hosts.length > 0) {
-                    volService.resizeVolumeOnHypervisor(volumeId, newSize, 
hosts[0], instanceName);
-                }
-
-                volume.setSize(newSize);
-            }
-
             if (newDiskOfferingId != null) {
                 volume.setDiskOfferingId(newDiskOfferingId);
             }
+
             _volsDao.update(volume.getId(), volume);
             // Log usage event for volumes belonging user VM's only
             UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_RESIZE, 
volume.getAccountId(), volume.getDataCenterId(), volume.getId(), 
volume.getName(),

Reply via email to