Updated Branches: refs/heads/4.2 5e72ddec8 -> 725d281cb
Add cpu model for kvm guest.Now all the kvm guest's cpu model is 'QEMU Virtual CPU version xxx'. This will affect the activation of Windows OS and low performance. I add three mode for user to indicate the guest cpu model.add libvirt version check Signed-off-by: Wei Zhou <w.z...@leaseweb.com> (cherry picked from commit 2903bb5fd9d59803980102854d11e33ebe56088b) Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/725d281c Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/725d281c Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/725d281c Branch: refs/heads/4.2 Commit: 725d281cb28c89b8f1536de769d7acf87f53fbe6 Parents: 5e72dde Author: JijunLiu <jiju...@gmail.com> Authored: Sun Jul 14 11:21:39 2013 +0800 Committer: Wei Zhou <w.z...@leaseweb.com> Committed: Fri Aug 2 11:59:02 2013 +0200 ---------------------------------------------------------------------- agent/conf/agent.properties | 20 +++++++++++++++ .../kvm/resource/LibvirtComputingResource.java | 27 ++++++++++++++++++++ .../hypervisor/kvm/resource/LibvirtVMDef.java | 27 ++++++++++++++++++++ .../kvm/resource/LibvirtVMDefTest.java | 20 +++++++++++++++ 4 files changed, 94 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/725d281c/agent/conf/agent.properties ---------------------------------------------------------------------- diff --git a/agent/conf/agent.properties b/agent/conf/agent.properties index 60030ae..5f5f368 100644 --- a/agent/conf/agent.properties +++ b/agent/conf/agent.properties @@ -94,3 +94,23 @@ domr.scripts.dir=scripts/network/domr/kvm # libvirt.vif.driver=com.cloud.hypervisor.kvm.resource.DirectVifDriver # network.direct.source.mode=private # network.direct.device=eth0 + +# setting to enable the cpu model to kvm guest globally. +# three option:custom,host-model and host-passthrough. +# custom - user custom the CPU model which specified by guest.cpu.model. +# host-model - identify the named CPU model which most closely matches the host, +# and then request additional CPU flags to complete the match. This should give +# close to maximum functionality/performance, which maintaining good +# reliability/compatibility if the guest is migrated to another host with slightly different host CPUs. +# host-passthrough - tell KVM to passthrough the host CPU with no modifications. +# The difference to host-model, instead of just matching feature flags, +# every last detail of the host CPU is matched. This gives absolutely best performance, +# and can be important to some apps which check low level CPU details, +# but it comes at a cost wrt migration. The guest can only be migrated to +# an exactly matching host CPU. +# +# guest.cpu.mode=custom|host-model|host-passthrough +# This param is only valid if guest.cpu.mode=custom, +# for examples:"Conroe" "Penryn", "Nehalem", "Westmere", "pentiumpro" and so +# on,run virsh capabilities for more details. +# guest.cpu.model= http://git-wip-us.apache.org/repos/asf/cloudstack/blob/725d281c/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 7330fa7..2ae21ad 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -192,6 +192,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.kvm.resource.KVMHABase.NfsStoragePool; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ClockDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ConsoleDef; +import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.CpuModeDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.CpuTuneDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DevicesDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; @@ -369,6 +370,8 @@ ServerResource { private boolean _can_bridge_firewall; protected String _localStoragePath; protected String _localStorageUUID; + protected String _guestCpuMode; + protected String _guestCpuModel; private final Map <String, String> _pifs = new HashMap<String, String>(); private final Map<String, vmStats> _vmStats = new ConcurrentHashMap<String, vmStats>(); @@ -760,6 +763,18 @@ ServerResource { s_logger.trace("Ignoring libvirt error.", e); } + _guestCpuMode = (String) params.get("guest.cpu.mode"); + if (_guestCpuMode != null) { + _guestCpuModel = (String) params.get("guest.cpu.model"); + + if(_hypervisorLibvirtVersion < (9 * 1000 + 10)) { + s_logger.warn("LibVirt version 0.9.10 required for guest cpu mode, but version " + + prettyVersion(_hypervisorLibvirtVersion) + " detected, so it will be disabled"); + _guestCpuMode = null; + _guestCpuModel = null; + } + } + String[] info = NetUtils.getNetworkParams(_privateNic); _monitor = new KVMHAMonitor(null, info[0], _heartBeatPath); @@ -3289,6 +3304,11 @@ ServerResource { grd.setVcpuNum(vmTO.getCpus()); vm.addComp(grd); + CpuModeDef cmd = new CpuModeDef(); + cmd.setMode(_guestCpuMode); + cmd.setModel(_guestCpuModel); + vm.addComp(cmd); + CpuTuneDef ctd = new CpuTuneDef(); /** A 4.0.X/4.1.X management server doesn't send the correct JSON @@ -4953,6 +4973,13 @@ ServerResource { return new Answer(cmd, success, ""); } + private String prettyVersion(long version) { + long major = version / 1000000; + long minor = version % 1000000 / 1000; + long release = version % 1000000 % 1000; + return major + "." + minor + "." + release; + } + @Override public void setName(String name) { // TODO Auto-generated method stub http://git-wip-us.apache.org/repos/asf/cloudstack/blob/725d281c/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java index 5120870..9a3bef9 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java @@ -938,6 +938,33 @@ public class LibvirtVMDef { } } + public static class CpuModeDef { + private String _mode; + private String _model; + + public void setMode(String mode) { + _mode = mode; + } + + public void setModel(String model) { + _model = model; + } + + @Override + public String toString() { + StringBuilder modeBuidler = new StringBuilder(); + if ("custom".equalsIgnoreCase(_mode) && _model != null) { + modeBuidler.append("<cpu mode='custom' match='exact'><model fallback='allow'>" + + _model + "</model></cpu>"); + } else if ("host-model".equals(_mode)) { + modeBuidler.append("<cpu mode='host-model'><model fallback='allow'></model></cpu>"); + } else if ("host-passthrough".equals(_mode)) { + modeBuidler.append("<cpu mode='host-passthrough'></cpu>"); + } + return modeBuidler.toString(); + } + } + public static class SerialDef { private final String _type; private final String _source; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/725d281c/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java index 2c0ff8d..9db2902 100644 --- a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java +++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java @@ -49,4 +49,24 @@ public class LibvirtVMDefTest extends TestCase { assertEquals(expected, ifDef.toString()); } + public void testCpuModeDef(){ + LibvirtVMDef.CpuModeDef cpuModeDef = new LibvirtVMDef.CpuModeDef(); + cpuModeDef.setMode("custom"); + cpuModeDef.setModel("Nehalem"); + + String expected1 = "<cpu mode='custom' match='exact'><model fallback='allow'>Nehalem</model></cpu>"; + + assertEquals(expected1, cpuModeDef.toString()); + + cpuModeDef.setMode("host-model"); + String expected2 = "<cpu mode='host-model'><model fallback='allow'></model></cpu>"; + + assertEquals(expected2, cpuModeDef.toString()); + + cpuModeDef.setMode("host-passthrough"); + String expected3 = "<cpu mode='host-passthrough'></cpu>"; + assertEquals(expected3, cpuModeDef.toString()); + + } + }