From b83b8eb838546197151d96e99ab3b9ee68db7df8 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Thu, 13 Jun 2013 15:56:21 +0530 Subject: [PATCH] CLOUDSTACK-2502: Scalevm and over provisioning should respect each other During Scale up of VM, memory/cpu calculations should consider the memory/cpu overprovisioning factors which are set per cluster. CLOUDSTACK-2939: CPU limit is not getting set for vm after scaleup to a service offering which have cpu cap enabled Signed-off-by: Abhinandan Prateek --- .../com/cloud/agent/api/ScaleVmCommand.java | 26 +++++++++++++------ .../vmware/resource/VmwareResource.java | 4 +-- .../vmware/resource/VmwareResourceTest.java | 7 ++--- .../xen/resource/CitrixResourceBase.java | 8 +++--- .../xen/resource/CitrixResourceBaseTest.java | 12 +++++++-- .../cloud/hypervisor/HypervisorGuruBase.java | 2 +- .../cloud/vm/VirtualMachineManagerImpl.java | 9 ++++++- .../vm/VirtualMachineManagerImplTest.java | 13 +++++++++- 8 files changed, 59 insertions(+), 22 deletions(-) diff --git a/core/src/com/cloud/agent/api/ScaleVmCommand.java b/core/src/com/cloud/agent/api/ScaleVmCommand.java index 35d22ad9d96..b3614856361 100644 --- a/core/src/com/cloud/agent/api/ScaleVmCommand.java +++ b/core/src/com/cloud/agent/api/ScaleVmCommand.java @@ -23,7 +23,8 @@ public class ScaleVmCommand extends Command { VirtualMachineTO vm; String vmName; int cpus; - Integer speed; + Integer minSpeed; + Integer maxSpeed; long minRam; long maxRam; @@ -40,14 +41,15 @@ public class ScaleVmCommand extends Command { } public ScaleVmCommand(String vmName, int cpus, - Integer speed, long minRam, long maxRam, boolean limitCpuUse) { + Integer minSpeed, Integer maxSpeed, long minRam, long maxRam, boolean limitCpuUse) { super(); this.vmName = vmName; this.cpus = cpus; - this.speed = speed; + this.minSpeed = minSpeed; + this.maxSpeed = maxSpeed; this.minRam = minRam; this.maxRam = maxRam; - this.vm = new VirtualMachineTO(1L, vmName, null, cpus, speed, minRam, maxRam, null, null, false, false, null); + this.vm = new VirtualMachineTO(1L, vmName, null, cpus, minSpeed, maxSpeed, minRam, maxRam, null, null, false, limitCpuUse, null); /*vm.setName(vmName); vm.setCpus(cpus); vm.setRam(minRam, maxRam);*/ @@ -57,14 +59,22 @@ public class ScaleVmCommand extends Command { this.cpus = cpus; } - public Integer getSpeed() { - return speed; + public Integer getMinSpeed() { + return minSpeed; } - public void setSpeed(Integer speed) { - this.speed = speed; + public void setMinSpeed(Integer minSpeed) { + this.minSpeed = minSpeed; } + public Integer getMaxSpeed() { + return minSpeed; + } + + public void setMaxSpeed(Integer maxSpeed) { + this.maxSpeed = maxSpeed; + } + public long getMinRam() { return minRam; } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 1f5eac2e448..1af42390366 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -2330,9 +2330,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa VmwareHypervisorHost hyperHost = getHyperHost(context); VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName()); VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); - int ramMb = (int) (vmSpec.getMinRam()); + int ramMb = (int) (vmSpec.getMinRam()/(1024 * 1024)); - VmwareHelper.setVmScaleUpConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getSpeed(), vmSpec.getSpeed(),(int) (vmSpec.getMaxRam()), ramMb, vmSpec.getLimitCpuUse()); + VmwareHelper.setVmScaleUpConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(), vmSpec.getMinSpeed(),(int) (vmSpec.getMaxRam()/(1024 * 1024)), ramMb, vmSpec.getLimitCpuUse()); if(!vmMo.configureVm(vmConfigSpec)) { throw new Exception("Unable to execute ScaleVmCommand"); diff --git a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java index 3ca0b600e36..2f7160873a8 100644 --- a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java +++ b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java @@ -68,10 +68,11 @@ public class VmwareResourceTest { when(_resource.getHyperHost(context, null)).thenReturn(hyperHost); doReturn("i-2-3-VM").when(cmd).getVmName(); when(hyperHost.findVmOnHyperHost("i-2-3-VM")).thenReturn(vmMo); - doReturn(1024L).when(vmSpec).getMinRam(); + doReturn(536870912L).when(vmSpec).getMinRam(); doReturn(1).when(vmSpec).getCpus(); - doReturn(1000).when(vmSpec).getSpeed(); - doReturn(1024L).when(vmSpec).getMaxRam(); + doReturn(1000).when(vmSpec).getMinSpeed(); + doReturn(1000).when(vmSpec).getMaxSpeed(); + doReturn(536870912L).when(vmSpec).getMaxRam(); doReturn(false).when(vmSpec).getLimitCpuUse(); when(vmMo.configureVm(vmConfigSpec)).thenReturn(true); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index e92c3fc55fe..5e8283ac35c 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -635,16 +635,16 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Long staticMemoryMax = vm.getMemoryStaticMax(conn); Long staticMemoryMin = vm.getMemoryStaticMin(conn); - Long newDynamicMemoryMin = vmSpec.getMinRam() * 1024 * 1024; - Long newDynamicMemoryMax = vmSpec.getMaxRam() * 1024 * 1024; + Long newDynamicMemoryMin = vmSpec.getMinRam(); + Long newDynamicMemoryMax = vmSpec.getMaxRam(); if (staticMemoryMin > newDynamicMemoryMin || newDynamicMemoryMax > staticMemoryMax) { throw new CloudRuntimeException("Cannot scale up the vm because of memory constraint violation: 0 <= memory-static-min <= memory-dynamic-min <= memory-dynamic-max <= memory-static-max "); } - vm.setMemoryDynamicRange(conn, vmSpec.getMinRam() * 1024 * 1024, vmSpec.getMaxRam() * 1024 * 1024); + vm.setMemoryDynamicRange(conn, newDynamicMemoryMin, newDynamicMemoryMax); vm.setVCPUsNumberLive(conn, (long)vmSpec.getCpus()); - Integer speed = vmSpec.getSpeed(); + Integer speed = vmSpec.getMinSpeed(); if (speed != null) { int cpuWeight = _maxWeight; //cpu_weight diff --git a/plugins/hypervisors/xen/test/com/cloud/hypervisor/xen/resource/CitrixResourceBaseTest.java b/plugins/hypervisors/xen/test/com/cloud/hypervisor/xen/resource/CitrixResourceBaseTest.java index 3328d4be50c..cb16ae2be15 100644 --- a/plugins/hypervisors/xen/test/com/cloud/hypervisor/xen/resource/CitrixResourceBaseTest.java +++ b/plugins/hypervisors/xen/test/com/cloud/hypervisor/xen/resource/CitrixResourceBaseTest.java @@ -113,10 +113,14 @@ public class CitrixResourceBaseTest { @Test public void testScaleVMF2() throws Types.XenAPIException, XmlRpcException { + when(vm.getMemoryStaticMax(conn)).thenReturn(1073741824L); + when(vm.getMemoryStaticMin(conn)).thenReturn(268435456L); + doReturn(536870912L).when(vmSpec).getMinRam(); + doReturn(536870912L).when(vmSpec).getMaxRam(); doNothing().when(vm).setMemoryDynamicRange(conn, 536870912L, 536870912L); doReturn(1).when(vmSpec).getCpus(); doNothing().when(vm).setVCPUsNumberLive(conn, 1L); - doReturn(500).when(vmSpec).getSpeed(); + doReturn(500).when(vmSpec).getMinSpeed(); doReturn(false).when(vmSpec).getLimitCpuUse(); Map args = (Map)mock(HashMap.class); when(host.callPlugin(conn, "vmops", "add_to_VCPUs_params_live", args)).thenReturn("Success"); @@ -132,10 +136,14 @@ public class CitrixResourceBaseTest { @Test public void testScaleVMF3() throws Types.XenAPIException, XmlRpcException { + when(vm.getMemoryStaticMax(conn)).thenReturn(1073741824L); + when(vm.getMemoryStaticMin(conn)).thenReturn(268435456L); + doReturn(536870912L).when(vmSpec).getMinRam(); + doReturn(536870912L).when(vmSpec).getMaxRam(); doNothing().when(vm).setMemoryDynamicRange(conn, 536870912L, 536870912L); doReturn(1).when(vmSpec).getCpus(); doNothing().when(vm).setVCPUsNumberLive(conn, 1L); - doReturn(500).when(vmSpec).getSpeed(); + doReturn(500).when(vmSpec).getMinSpeed(); doReturn(true).when(vmSpec).getLimitCpuUse(); doReturn(null).when(_resource).callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "cap", "value", "100", "vmname", "i-2-3-VM"); Map args = (Map)mock(HashMap.class); diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java index d8945af9b8c..1ad9a1fb7c4 100644 --- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java @@ -86,7 +86,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis } - protected VirtualMachineTO toVirtualMachineTO(VirtualMachineProfile vmProfile) { + protected VirtualMachineTO toVirtualMachineTO(VirtualMachineProfile vmProfile) { ServiceOffering offering = vmProfile.getServiceOffering(); VirtualMachine vm = vmProfile.getVirtualMachine(); diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 568fe558247..f946cd1ebf6 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -129,6 +129,7 @@ import com.cloud.network.rules.RulesManager; import com.cloud.offering.ServiceOffering; import com.cloud.org.Cluster; import com.cloud.resource.ResourceManager; +import com.cloud.server.ConfigurationServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; @@ -256,6 +257,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac protected RulesManager rulesMgr; @Inject protected AffinityGroupVMMapDao _affinityGroupVMMapDao; + @Inject + protected ConfigurationServer _configServer; protected List _planners; public List getPlanners() { @@ -3226,8 +3229,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac long newServiceofferingId = vm.getServiceOfferingId(); ServiceOffering newServiceOffering = _configMgr.getServiceOffering(newServiceofferingId); + HostVO hostVo = _hostDao.findById(vm.hostId); + Float memoryOvercommitRatio = Float.parseFloat(_configServer.getConfigValue(Config.MemOverprovisioningFactor.key(), Config.ConfigurationParameterScope.cluster.toString(), hostVo.getClusterId())); + Float cpuOvercommitRatio = Float.parseFloat(_configServer.getConfigValue(Config.CPUOverprovisioningFactor.key(), Config.ConfigurationParameterScope.cluster.toString(), hostVo.getClusterId())); + long minMemory = (long) (newServiceOffering.getRamSize()/memoryOvercommitRatio); ScaleVmCommand reconfigureCmd = new ScaleVmCommand(vm.getInstanceName(), newServiceOffering.getCpu(), - newServiceOffering.getSpeed(), newServiceOffering.getRamSize(), newServiceOffering.getRamSize(), newServiceOffering.getLimitCpuUse()); + (int) (newServiceOffering.getSpeed()/cpuOvercommitRatio), newServiceOffering.getSpeed(), minMemory * 1024 * 1024, newServiceOffering.getRamSize() * 1024 * 1024, newServiceOffering.getLimitCpuUse()); Long dstHostId = vm.getHostId(); ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Running, vm.getType(), vm.getId()); diff --git a/server/test/com/cloud/vm/VirtualMachineManagerImplTest.java b/server/test/com/cloud/vm/VirtualMachineManagerImplTest.java index dd51e74a618..8715c9e8663 100644 --- a/server/test/com/cloud/vm/VirtualMachineManagerImplTest.java +++ b/server/test/com/cloud/vm/VirtualMachineManagerImplTest.java @@ -22,11 +22,13 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.ScaleVmAnswer; import com.cloud.agent.api.ScaleVmCommand; import com.cloud.capacity.CapacityManager; +import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.deploy.DeployDestination; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; +import com.cloud.server.ConfigurationServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VolumeManager; @@ -154,6 +156,10 @@ public class VirtualMachineManagerImplTest { List _rootVols; @Mock ItWorkVO _work; + @Mock + ConfigurationServer _configServer; + @Mock + HostVO hostVO; @Mock ClusterDao _clusterDao; @Mock HostPodDao _podDao; @@ -199,6 +205,7 @@ public class VirtualMachineManagerImplTest { _vmMgr._hvGuruMgr = _hvGuruMgr; _vmMgr._vmSnapshotMgr = _vmSnapshotMgr; _vmMgr._vmDao = _vmInstanceDao; + _vmMgr._configServer = _configServer; when(_vmMock.getId()).thenReturn(314l); when(_vmInstance.getId()).thenReturn(1L); @@ -239,8 +246,12 @@ public class VirtualMachineManagerImplTest { when(_vmInstanceDao.findById(anyLong())).thenReturn(_vmInstance); ServiceOfferingVO newServiceOffering = getSvcoffering(512); + when(_hostDao.findById(_vmInstance.hostId)).thenReturn(hostVO); + doReturn(1L).when(hostVO).getClusterId(); + when(_configServer.getConfigValue(Config.MemOverprovisioningFactor.key(), Config.ConfigurationParameterScope.cluster.toString(), 1L)).thenReturn("1.0"); + when(_configServer.getConfigValue(Config.CPUOverprovisioningFactor.key(), Config.ConfigurationParameterScope.cluster.toString(), 1L)).thenReturn("1.0"); ScaleVmCommand reconfigureCmd = new ScaleVmCommand("myVmName", newServiceOffering.getCpu(), - newServiceOffering.getSpeed(), newServiceOffering.getRamSize(), newServiceOffering.getRamSize(), newServiceOffering.getLimitCpuUse()); + newServiceOffering.getSpeed(), newServiceOffering.getSpeed(), newServiceOffering.getRamSize(), newServiceOffering.getRamSize(), newServiceOffering.getLimitCpuUse()); Answer answer = new ScaleVmAnswer(reconfigureCmd, true, "details"); when(_agentMgr.send(2l, reconfigureCmd)).thenReturn(null); _vmMgr.reConfigureVm(_vmInstance, getSvcoffering(256), false);