diff --git a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java index 4b36df5827f..3e508eea315 100644 --- a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java +++ b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java @@ -61,6 +61,7 @@ public class VirtualMachineTO { DiskTO[] disks; NicTO[] nics; GPUDeviceTO gpuDevice; + Integer vcpuMaxLimit; public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer speed, long minRam, long maxRam, BootloaderType bootloader, String os, boolean enableHA, boolean limitCpuUse, String vncPassword) { @@ -283,4 +284,12 @@ public class VirtualMachineTO { this.platformEmulator = platformEmulator; } + public Integer getVcpuMaxLimit() { + return vcpuMaxLimit; + } + + public void setVcpuMaxLimit(Integer vcpuMaxLimit) { + this.vcpuMaxLimit = vcpuMaxLimit; + } + } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java index 89c204638b6..b17048b435c 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java @@ -26,12 +26,14 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.hypervisor.xenserver.XenserverConfigs; import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.command.DettachCommand; import org.apache.cloudstack.storage.command.StorageSubSystemCommand; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.cloudstack.framework.config.ConfigKey; import com.cloud.agent.api.Command; import com.cloud.agent.api.to.DataObjectType; @@ -51,11 +53,13 @@ import com.cloud.storage.dao.GuestOSHypervisorDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.Pair; +import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.dao.UserVmDao; @Local(value = HypervisorGuru.class) -public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru { +public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru, Configurable { @Inject GuestOSDao _guestOsDao; @Inject @@ -70,6 +74,11 @@ public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru PrimaryDataStoreDao _storagePoolDao; @Inject VolumeDataFactory _volFactory; + @Inject + UserVmDao _userVmDao; + + static final ConfigKey MaxNumberOfVCPUSPerVM = new ConfigKey("Advanced", Integer.class, "xen.vm.vcpu.max", "16", + "Maximum number of VCPUs that VM can get in XenServer.", true, ConfigKey.Scope.Cluster); protected XenServerGuru() { super(); @@ -87,6 +96,14 @@ public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru bt = vm.getBootLoaderType(); } VirtualMachineTO to = toVirtualMachineTO(vm); + UserVmVO userVmVO = _userVmDao.findById(vm.getId()); + if (userVmVO != null) { + HostVO host = hostDao.findById(userVmVO.getHostId()); + if (host != null) { + to.setVcpuMaxLimit(MaxNumberOfVCPUSPerVM.valueIn(host.getClusterId())); + } + } + to.setBootloader(bt); // Determine the VM's OS description @@ -176,4 +193,14 @@ public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru } return new Pair(Boolean.FALSE, new Long(hostId)); } + + @Override + public String getConfigComponentName() { + return XenServerGuru.class.getSimpleName(); + } + + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[] {MaxNumberOfVCPUSPerVM}; + } } 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 a090b1106ac..b4e5cbc2467 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 @@ -1326,6 +1326,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe vmr.actionsAfterCrash = Types.OnCrashBehaviour.DESTROY; vmr.actionsAfterShutdown = Types.OnNormalExit.DESTROY; vmr.otherConfig.put("vm_uuid", vmSpec.getUuid()); + vmr.VCPUsMax = (long) vmSpec.getCpus(); // FIX ME: In case of dynamic scaling this VCPU max should be the minumum of + // recommended value for that template and capacity remaining on host if (isDmcEnabled(conn, host) && vmSpec.isEnableDynamicallyScaleVm()) { //scaling is allowed @@ -1334,13 +1336,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe vmr.memoryDynamicMin = vmSpec.getMinRam(); vmr.memoryDynamicMax = vmSpec.getMaxRam(); if (guestOsTypeName.toLowerCase().contains("windows")) { - vmr.VCPUsMax = (long)vmSpec.getCpus(); + vmr.VCPUsMax = (long) vmSpec.getCpus(); } else { - // XenServer has a documented limit of 16 vcpus per vm - vmr.VCPUsMax = 2L * vmSpec.getCpus(); - if (vmr.VCPUsMax > 16) - { - vmr.VCPUsMax = 16L; + if (vmSpec.getVcpuMaxLimit() != null) { + vmr.VCPUsMax = (long) vmSpec.getVcpuMaxLimit(); } } } else { @@ -1352,11 +1351,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe vmr.memoryStaticMax = vmSpec.getMaxRam(); vmr.memoryDynamicMin = vmSpec.getMaxRam();; vmr.memoryDynamicMax = vmSpec.getMaxRam(); - vmr.VCPUsMax = (long)vmSpec.getCpus(); + + vmr.VCPUsMax = (long) vmSpec.getCpus(); } - - vmr.VCPUsAtStartup = (long)vmSpec.getCpus(); + vmr.VCPUsAtStartup = (long) vmSpec.getCpus(); vmr.consoles.clear(); VM vm = VM.create(conn, vmr);