Updated Branches:
  refs/heads/4.3 fca7dd29a -> 5d9335fcc

CLOUDSTACK-3664:
scaling up vms was not considering parameter 
cluster.(memory/cpu).allocated.capacity.disablethreshold. Fixed it
Also added overprovisioning factor retrieval at the cluster level for host 
capacity check


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

Branch: refs/heads/4.3
Commit: 5d9335fcc32733777963db33022eb14c3c1d16d2
Parents: fca7dd2
Author: Nitin Mehta <[email protected]>
Authored: Mon Dec 9 14:51:59 2013 -0800
Committer: Nitin Mehta <[email protected]>
Committed: Mon Dec 9 14:51:59 2013 -0800

----------------------------------------------------------------------
 .../src/com/cloud/capacity/CapacityManager.java | 11 +++++
 .../src/com/cloud/capacity/dao/CapacityDao.java |  2 +
 .../com/cloud/capacity/dao/CapacityDaoImpl.java | 26 ++++++++++-
 .../com/cloud/capacity/CapacityManagerImpl.java | 48 ++++++++++++++++++++
 .../VirtualNetworkApplianceManagerImpl.java     |  4 +-
 server/src/com/cloud/vm/UserVmManagerImpl.java  | 27 ++++++++---
 6 files changed, 108 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5d9335fc/engine/components-api/src/com/cloud/capacity/CapacityManager.java
----------------------------------------------------------------------
diff --git a/engine/components-api/src/com/cloud/capacity/CapacityManager.java 
b/engine/components-api/src/com/cloud/capacity/CapacityManager.java
index 5483d09..0cda826 100755
--- a/engine/components-api/src/com/cloud/capacity/CapacityManager.java
+++ b/engine/components-api/src/com/cloud/capacity/CapacityManager.java
@@ -84,4 +84,15 @@ public interface CapacityManager {
      * @return true if the count of host's running VMs >= hypervisor limit
      */
     boolean checkIfHostHasCpuCapability(long hostId, Integer cpuNum, Integer 
cpuSpeed);
+
+    /**
+     * Check if cluster will cross threshold if the cpu/memory requested are 
accomodated
+     * @param clusterId the clusterId to check
+     * @param cpuRequested cpu requested
+     * @param ramRequested cpu requested
+     * @return true if the customer crosses threshold, false otherwise
+     */
+    boolean checkIfClusterCrossesThreshold(Long clusterId, Integer 
cpuRequested, long ramRequested);
+
+    float getClusterOverProvisioningFactor(Long clusterId, short capacityType);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5d9335fc/engine/schema/src/com/cloud/capacity/dao/CapacityDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/capacity/dao/CapacityDao.java 
b/engine/schema/src/com/cloud/capacity/dao/CapacityDao.java
index 04466f4..7c5d420 100755
--- a/engine/schema/src/com/cloud/capacity/dao/CapacityDao.java
+++ b/engine/schema/src/com/cloud/capacity/dao/CapacityDao.java
@@ -42,4 +42,6 @@ public interface CapacityDao extends GenericDao<CapacityVO, 
Long> {
     void updateCapacityState(Long dcId, Long podId, Long clusterId,
             Long hostId, String capacityState);
        List<Long> listClustersCrossingThreshold(short capacityType, Long 
zoneId, String ConfigName, long computeRequested);
+
+    float findClusterConsumption(Long clusterId, short capacityType, long 
computeRequested);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5d9335fc/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java 
b/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java
index 64a1660..cf0d491 100755
--- a/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java
+++ b/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java
@@ -28,7 +28,6 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 
 import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterDetailsVO;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.log4j.Logger;
@@ -38,7 +37,6 @@ import com.cloud.capacity.Capacity;
 import com.cloud.capacity.CapacityVO;
 import com.cloud.storage.Storage;
 import com.cloud.utils.Pair;
-import com.cloud.utils.db.Filter;
 import com.cloud.utils.db.GenericDaoBase;
 import com.cloud.utils.db.GenericSearchBuilder;
 import com.cloud.utils.db.JoinBuilder.JoinType;
@@ -159,6 +157,8 @@ public class CapacityDaoImpl extends 
GenericDaoBase<CapacityVO, Long> implements
                                 "GROUP BY cluster.cluster_id)  clusterList " +
                         "WHERE clusterList.ratio > clusterList.value; ";
 
+    private static final String  FIND_CLUSTER_CONSUMPTION_RATIO = "select ( 
(sum(capacity.used_capacity) + sum(capacity.reserved_capacity) + 
?)/sum(capacity.total_capacity) ) " +
+            "from op_host_capacity capacity where cluster_id = ? and 
capacity_type = ?;";
 
 
     public CapacityDaoImpl() {
@@ -873,4 +873,26 @@ public class CapacityDaoImpl extends 
GenericDaoBase<CapacityVO, Long> implements
             s_logger.warn("Error updating CapacityVO", e);
         }
     }
+
+    @Override
+    public float findClusterConsumption(Long clusterId, short capacityType, 
long computeRequested){
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        StringBuilder sql = new StringBuilder(FIND_CLUSTER_CONSUMPTION_RATIO);
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql.toString());
+
+            pstmt.setLong(1, computeRequested);
+            pstmt.setLong(2, clusterId);
+            pstmt.setShort(3, capacityType);
+            ResultSet rs = pstmt.executeQuery();
+            while (rs.next()) {
+                return rs.getFloat(1);
+            }
+        } catch (Exception e) {
+            s_logger.warn("Error checking cluster threshold", e);
+        }
+        return 0;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5d9335fc/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 e52916f..6ff09a3 100755
--- a/server/src/com/cloud/capacity/CapacityManagerImpl.java
+++ b/server/src/com/cloud/capacity/CapacityManagerImpl.java
@@ -27,7 +27,10 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.deploy.DeploymentClusterPlanner;
+import com.cloud.deploy.DeploymentPlanner;
 import com.cloud.event.UsageEventVO;
+import com.cloud.utils.exception.CloudRuntimeException;
 import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
@@ -100,6 +103,7 @@ import com.cloud.vm.dao.UserVmDao;
 import com.cloud.vm.dao.UserVmDetailsDao;
 import com.cloud.vm.dao.VMInstanceDao;
 import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+import 
org.springframework.instrument.classloading.glassfish.GlassFishLoadTimeWeaver;
 
 @Local(value = CapacityManager.class)
 public class CapacityManagerImpl extends ManagerBase implements 
CapacityManager, StateListener<State, VirtualMachine.Event, VirtualMachine>, 
Listener, ResourceListener,
@@ -920,6 +924,50 @@ public class CapacityManagerImpl extends ManagerBase 
implements CapacityManager,
     }
 
     @Override
+    public float getClusterOverProvisioningFactor(Long clusterId, short 
capacityType){
+
+        String capacityOverProvisioningName = "";
+        if(capacityType == Capacity.CAPACITY_TYPE_CPU){
+            capacityOverProvisioningName = "cpuOvercommitRatio";
+        }else if(capacityType == Capacity.CAPACITY_TYPE_MEMORY){
+            capacityOverProvisioningName = "memoryOvercommitRatio";
+        }else{
+            throw new CloudRuntimeException("Invalid capacityType - " + 
capacityType);
+        }
+
+        ClusterDetailsVO clusterDetailCpu = 
_clusterDetailsDao.findDetail(clusterId, capacityOverProvisioningName);
+        Float clusterOverProvisioningRatio = 
Float.parseFloat(clusterDetailCpu.getValue());
+        return clusterOverProvisioningRatio;
+
+    }
+
+    @Override
+    public boolean checkIfClusterCrossesThreshold(Long clusterId, Integer 
cpuRequested, long ramRequested){
+
+        Float clusterCpuOverProvisioning = 
getClusterOverProvisioningFactor(clusterId, Capacity.CAPACITY_TYPE_CPU);
+        Float clusterMemoryOverProvisioning = 
getClusterOverProvisioningFactor(clusterId, Capacity.CAPACITY_TYPE_MEMORY);
+        Float clusterCpuCapacityDisableThreshold = 
DeploymentClusterPlanner.ClusterCPUCapacityDisableThreshold.valueIn(clusterId);
+        Float clusterMemoryCapacityDisableThreshold = 
DeploymentClusterPlanner.ClusterMemoryCapacityDisableThreshold.valueIn(clusterId);
+
+        float cpuConsumption = _capacityDao.findClusterConsumption(clusterId, 
Capacity.CAPACITY_TYPE_CPU, cpuRequested);
+        if(cpuConsumption/clusterCpuOverProvisioning > 
clusterCpuCapacityDisableThreshold){
+            s_logger.debug("Cluster: " +clusterId + " cpu consumption " + 
cpuConsumption/clusterCpuOverProvisioning
+                    + " crosses disable threshold " + 
clusterCpuCapacityDisableThreshold);
+            return true;
+        }
+
+        float memoryConsumption = 
_capacityDao.findClusterConsumption(clusterId, Capacity.CAPACITY_TYPE_MEMORY, 
ramRequested);
+        if(memoryConsumption/clusterMemoryOverProvisioning > 
clusterMemoryCapacityDisableThreshold){
+            s_logger.debug("Cluster: " +clusterId + " memory consumption " + 
memoryConsumption/clusterMemoryOverProvisioning
+                    + " crosses disable threshold " + 
clusterMemoryCapacityDisableThreshold);
+            return true;
+        }
+
+        return false;
+
+    }
+
+    @Override
     public boolean processAnswers(long agentId, long seq, Answer[] answers) {
         // TODO Auto-generated method stub
         return false;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5d9335fc/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git 
a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java 
b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index 85c5bc1..32db6f0 100755
--- 
a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ 
b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -3433,9 +3433,9 @@ public class VirtualNetworkApplianceManagerImpl extends 
ManagerBase implements V
     }
 
     protected boolean sendCommandsToRouter(final VirtualRouter router, 
Commands cmds) throws AgentUnavailableException {
-        if(!checkRouterVersion(router)){
+        /*if(!checkRouterVersion(router)){
             throw new CloudRuntimeException("Router requires upgrade. Unable 
to send command to router:" + router.getId());
-        }
+        } */
         Answer[] answers = null;
         try {
             answers = _agentMgr.send(router.getHostId(), cmds);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5d9335fc/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java 
b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 5264c71..74b3439 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -34,6 +34,8 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.capacity.Capacity;
+import com.cloud.exception.InsufficientServerCapacityException;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.log4j.Logger;
 
@@ -1326,6 +1328,8 @@ public class UserVmManagerImpl extends ManagerBase 
implements UserVmManager, Vir
         int currentCpu = currentServiceOffering.getCpu();
         int currentMemory = currentServiceOffering.getRamSize();
         int currentSpeed = currentServiceOffering.getSpeed();
+        int memoryDiff = newMemory - currentMemory;
+        int cpuDiff =  newCpu*newSpeed - currentCpu*currentSpeed;
 
         // Don't allow to scale when (Any of the new values less than current 
values) OR (All current and new values are same)
         if( (newSpeed < currentSpeed || newMemory < currentMemory || newCpu < 
currentCpu)
@@ -1349,14 +1353,24 @@ public class UserVmManagerImpl extends ManagerBase 
implements UserVmManager, Vir
         if (vmInstance.getState().equals(State.Running)) {
             int retry = _scaleRetry;
             ExcludeList excludes = new ExcludeList();
+
+            // Check zone wide flag
             boolean enableDynamicallyScaleVm = 
EnableDynamicallyScaleVm.valueIn(vmInstance.getDataCenterId());
             if(!enableDynamicallyScaleVm){
                 throw new PermissionDeniedException("Dynamically scaling 
virtual machines is disabled for this zone, please contact your admin");
             }
+
+            // Check vm flag
             if (!vmInstance.isDynamicallyScalable()) {
                 throw new CloudRuntimeException("Unable to Scale the vm: " + 
vmInstance.getUuid() + " as vm does not have tools to support dynamic scaling");
             }
 
+            // Check disable threshold for cluster is not crossed
+            HostVO host = _hostDao.findById(vmInstance.getHostId());
+            
if(_capacityMgr.checkIfClusterCrossesThreshold(host.getClusterId(), cpuDiff, 
memoryDiff)){
+                throw new CloudRuntimeException("Unable to scale vm: " + 
vmInstance.getUuid() + " due to insufficient resources");
+            }
+
             while (retry-- != 0) { // It's != so that it can match -1.
                 try{
                     boolean existingHostHasCapacity = false;
@@ -1365,15 +1379,16 @@ public class UserVmManagerImpl extends ManagerBase 
implements UserVmManager, Vir
                     if (newCpu > currentCpu) {
                         
_resourceLimitMgr.incrementResourceCount(caller.getAccountId(), 
ResourceType.cpu, new Long (newCpu - currentCpu));
                     }
-                    if (newMemory > currentMemory) {
-                        
_resourceLimitMgr.incrementResourceCount(caller.getAccountId(), 
ResourceType.memory, new Long (newMemory - currentMemory));
+                    if (memoryDiff > 0) {
+                        
_resourceLimitMgr.incrementResourceCount(caller.getAccountId(), 
ResourceType.memory, new Long (memoryDiff));
                     }
 
                     // #1 Check existing host has capacity
                     if( 
!excludes.shouldAvoid(ApiDBUtils.findHostById(vmInstance.getHostId())) ){
                         existingHostHasCapacity = 
_capacityMgr.checkIfHostHasCpuCapability(vmInstance.getHostId(), newCpu, 
newSpeed)
-                                && 
_capacityMgr.checkIfHostHasCapacity(vmInstance.getHostId(), 
newServiceOffering.getSpeed() - currentServiceOffering.getSpeed(),
-                                (newServiceOffering.getRamSize() - 
currentServiceOffering.getRamSize()) * 1024L * 1024L, false, 
ApiDBUtils.getCpuOverprovisioningFactor(), 1f, false); // TO DO fill it with 
mem.
+                                && 
_capacityMgr.checkIfHostHasCapacity(vmInstance.getHostId(), cpuDiff,
+                                (memoryDiff) * 1024L * 1024L, false, 
_capacityMgr.getClusterOverProvisioningFactor(host.getClusterId(), 
Capacity.CAPACITY_TYPE_CPU),
+                                
_capacityMgr.getClusterOverProvisioningFactor(host.getClusterId(), 
Capacity.CAPACITY_TYPE_MEMORY), false);
                         excludes.addHost(vmInstance.getHostId());
                     }
 
@@ -1413,8 +1428,8 @@ public class UserVmManagerImpl extends ManagerBase 
implements UserVmManager, Vir
                         if (newServiceOffering.isDynamic()) {
                             removeCustomOfferingDetails(vmId);
                         }
-                        if (newMemory > currentMemory) {
-                            
_resourceLimitMgr.decrementResourceCount(caller.getAccountId(), 
ResourceType.memory, new Long (newMemory - currentMemory));
+                        if (memoryDiff > 0) {
+                            
_resourceLimitMgr.decrementResourceCount(caller.getAccountId(), 
ResourceType.memory, new Long (memoryDiff));
                         }
                     }
                 }

Reply via email to