diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java index b2b451c98fe..3e5ddbfcbc8 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -171,6 +171,7 @@ import com.cloud.host.Status; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.HypervisorGuru; +import com.cloud.hypervisor.HypervisorGuruBase; import com.cloud.hypervisor.HypervisorGuruManager; import com.cloud.network.Network; import com.cloud.network.NetworkModel; @@ -4659,34 +4660,43 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } } - private VMInstanceVO orchestrateReConfigureVm(final String vmUuid, final ServiceOffering oldServiceOffering, final ServiceOffering newServiceOffering, - final boolean reconfiguringOnExistingHost) throws ResourceUnavailableException, ConcurrentOperationException { - final VMInstanceVO vm = _vmDao.findByUuid(vmUuid); + private VMInstanceVO orchestrateReConfigureVm(String vmUuid, ServiceOffering oldServiceOffering, ServiceOffering newServiceOffering, + boolean reconfiguringOnExistingHost) throws ResourceUnavailableException, ConcurrentOperationException { + VMInstanceVO vm = _vmDao.findByUuid(vmUuid); upgradeVmDb(vm.getId(), newServiceOffering, oldServiceOffering); - final HostVO hostVo = _hostDao.findById(vm.getHostId()); - final Float memoryOvercommitRatio = CapacityManager.MemOverprovisioningFactor.valueIn(hostVo.getClusterId()); - final Float cpuOvercommitRatio = CapacityManager.CpuOverprovisioningFactor.valueIn(hostVo.getClusterId()); - final long minMemory = (long)(newServiceOffering.getRamSize() / memoryOvercommitRatio); - final ScaleVmCommand reconfigureCmd = - new ScaleVmCommand(vm.getInstanceName(), newServiceOffering.getCpu(), (int)(newServiceOffering.getSpeed() / cpuOvercommitRatio), + HostVO hostVo = _hostDao.findById(vm.getHostId()); + + Long clustedId = hostVo.getClusterId(); + Float memoryOvercommitRatio = CapacityManager.MemOverprovisioningFactor.valueIn(clustedId); + Float cpuOvercommitRatio = CapacityManager.CpuOverprovisioningFactor.valueIn(clustedId); + boolean divideMemoryByOverprovisioning = HypervisorGuruBase.VmMinMemoryEqualsMemoryDividedByMemOverprovisioningFactor.valueIn(clustedId); + boolean divideCpuByOverprovisioning = HypervisorGuruBase.VmMinCpuSpeedEqualsCpuSpeedDividedByCpuOverprovisioningFactor.valueIn(clustedId); + + int minMemory = (int)(newServiceOffering.getRamSize() / (divideMemoryByOverprovisioning ? memoryOvercommitRatio : 1)); + int minSpeed = (int)(newServiceOffering.getSpeed() / (divideCpuByOverprovisioning ? cpuOvercommitRatio : 1)); + + ScaleVmCommand scaleVmCommand = + new ScaleVmCommand(vm.getInstanceName(), newServiceOffering.getCpu(), minSpeed, newServiceOffering.getSpeed(), minMemory * 1024L * 1024L, newServiceOffering.getRamSize() * 1024L * 1024L, newServiceOffering.getLimitCpuUse()); - final Long dstHostId = vm.getHostId(); - if(vm.getHypervisorType().equals(HypervisorType.VMware)) { - final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); - Map details = null; - details = hvGuru.getClusterSettings(vm.getId()); - reconfigureCmd.getVirtualMachine().setDetails(details); + Long dstHostId = vm.getHostId(); + + if (vm.getHypervisorType().equals(HypervisorType.VMware)) { + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); + Map details = hvGuru.getClusterSettings(vm.getId()); + scaleVmCommand.getVirtualMachine().setDetails(details); } - final ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Running, vm.getType(), vm.getId()); + ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Running, vm.getType(), vm.getId()); work.setStep(Step.Prepare); work.setResourceType(ItWorkVO.ResourceType.Host); work.setResourceId(vm.getHostId()); _workDao.persist(work); + boolean success = false; + try { if (reconfiguringOnExistingHost) { vm.setServiceOfferingId(oldServiceOffering.getId()); @@ -4695,17 +4705,18 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _capacityMgr.allocateVmCapacity(vm, false); // lock the new capacity } - final Answer reconfigureAnswer = _agentMgr.send(vm.getHostId(), reconfigureCmd); - if (reconfigureAnswer == null || !reconfigureAnswer.getResult()) { - s_logger.error("Unable to scale vm due to " + (reconfigureAnswer == null ? "" : reconfigureAnswer.getDetails())); - throw new CloudRuntimeException("Unable to scale vm due to " + (reconfigureAnswer == null ? "" : reconfigureAnswer.getDetails())); + Answer scaleVmAnswer = _agentMgr.send(vm.getHostId(), scaleVmCommand); + if (scaleVmAnswer == null || !scaleVmAnswer.getResult()) { + String msg = String.format("Unable to scale %s due to [%s].", vm.toString(), (scaleVmAnswer == null ? "" : scaleVmAnswer.getDetails())); + s_logger.error(msg); + throw new CloudRuntimeException(msg); } if (vm.getType().equals(VirtualMachine.Type.User)) { _userVmMgr.generateUsageEvent(vm, vm.isDisplayVm(), EventTypes.EVENT_VM_DYNAMIC_SCALE); } success = true; - } catch (final OperationTimedoutException e) { - throw new AgentUnavailableException("Operation timed out on reconfiguring " + vm, dstHostId); + } catch (OperationTimedoutException e) { + throw new AgentUnavailableException(String.format("Unable to scale %s due to [%s].", vm.toString(), e.getMessage()), dstHostId, e); } catch (final AgentUnavailableException e) { throw e; } finally { diff --git a/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java index 1d3f34ee158..7d6c88870c0 100644 --- a/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java @@ -34,6 +34,8 @@ import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.gpu.GPU; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkDetailVO; @@ -49,7 +51,6 @@ import com.cloud.service.dao.ServiceOfferingDetailsDao; import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; import com.cloud.utils.Pair; -import com.cloud.utils.StringUtils; import com.cloud.utils.component.AdapterBase; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; @@ -61,8 +62,11 @@ import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.NicSecondaryIpDao; import com.cloud.vm.dao.UserVmDetailsDao; import com.cloud.vm.dao.VMInstanceDao; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; +import org.apache.commons.lang3.StringUtils; -public abstract class HypervisorGuruBase extends AdapterBase implements HypervisorGuru { +public abstract class HypervisorGuruBase extends AdapterBase implements HypervisorGuru, Configurable { public static final Logger s_logger = Logger.getLogger(HypervisorGuruBase.class); @Inject @@ -85,6 +89,14 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis private ServiceOfferingDao _serviceOfferingDao; @Inject private NetworkDetailsDao networkDetailsDao; + @Inject + private HostDao hostDao; + + public static ConfigKey VmMinMemoryEqualsMemoryDividedByMemOverprovisioningFactor = new ConfigKey("Advanced", Boolean.class, "vm.min.memory.equals.memory.divided.by.mem.overprovisioning.factor", "true", + "If we set this to 'true', a minimum memory (memory/ mem.overprovisioning.factor) will be set to the VM, independent of using a scalable service offering or not.", true, ConfigKey.Scope.Cluster); + + public static ConfigKey VmMinCpuSpeedEqualsCpuSpeedDividedByCpuOverprovisioningFactor = new ConfigKey("Advanced", Boolean.class, "vm.min.cpu.speed.equals.cpu.speed.divided.by.cpu.overprovisioning.factor", "true", + "If we set this to 'true', a minimum CPU speed (cpu speed/ cpu.overprovisioning.factor) will be set on the VM, independent of using a scalable service offering or not.", true, ConfigKey.Scope.Cluster); @Override public NicTO toNicTO(NicProfile profile) { @@ -167,8 +179,13 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis protected VirtualMachineTO toVirtualMachineTO(VirtualMachineProfile vmProfile) { ServiceOffering offering = _serviceOfferingDao.findById(vmProfile.getId(), vmProfile.getServiceOfferingId()); VirtualMachine vm = vmProfile.getVirtualMachine(); - Long minMemory = (long)(offering.getRamSize() / vmProfile.getMemoryOvercommitRatio()); - int minspeed = (int)(offering.getSpeed() / vmProfile.getCpuOvercommitRatio()); + HostVO host = hostDao.findById(vm.getHostId()); + + boolean divideMemoryByOverprovisioning = VmMinMemoryEqualsMemoryDividedByMemOverprovisioningFactor.valueIn(host.getClusterId()); + boolean divideCpuByOverprovisioning = VmMinCpuSpeedEqualsCpuSpeedDividedByCpuOverprovisioningFactor.valueIn(host.getClusterId()); + + Long minMemory = (long)(offering.getRamSize() / (divideMemoryByOverprovisioning ? vmProfile.getMemoryOvercommitRatio() : 1)); + int minspeed = (int)(offering.getSpeed() / (divideCpuByOverprovisioning ? vmProfile.getCpuOvercommitRatio() : 1)); int maxspeed = (offering.getSpeed()); VirtualMachineTO to = new VirtualMachineTO(vm.getId(), vm.getInstanceName(), vm.getType(), offering.getCpu(), minspeed, maxspeed, minMemory * 1024l * 1024l, offering.getRamSize() * 1024l * 1024l, null, null, vm.isHaEnabled(), vm.limitCpuUse(), vm.getVncPassword()); @@ -302,4 +319,15 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis public List finalizeMigrate(VirtualMachine vm, Map volumeToPool) { return null; } + + @Override + public String getConfigComponentName() { + return HypervisorGuruBase.class.getSimpleName(); + } + + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[] {VmMinMemoryEqualsMemoryDividedByMemOverprovisioningFactor, VmMinCpuSpeedEqualsCpuSpeedDividedByCpuOverprovisioningFactor }; + } + } diff --git a/tools/checkstyle/src/main/resources/cloud-style.xml b/tools/checkstyle/src/main/resources/cloud-style.xml index 6aaef17b926..4fad942fff0 100644 --- a/tools/checkstyle/src/main/resources/cloud-style.xml +++ b/tools/checkstyle/src/main/resources/cloud-style.xml @@ -30,7 +30,7 @@ - +