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.zhou@leaseweb.com>
This commit is contained in:
JijunLiu 2013-07-14 11:21:39 +08:00 committed by Wei Zhou
parent 0529da136f
commit 2903bb5fd9
4 changed files with 94 additions and 0 deletions

View File

@ -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=

View File

@ -191,6 +191,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;
@ -366,6 +367,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>();
@ -757,6 +760,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);
@ -3286,6 +3301,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
@ -4950,6 +4970,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

View File

@ -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;

View File

@ -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());
}
}