fix kvm issue, for windows sever 2008, it will crash without hyperv enlightment featre enabled
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/9319a4e5 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/9319a4e5 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/9319a4e5 Branch: refs/heads/4.5 Commit: 9319a4e5f87820fa16da67d32ae39f86b73841a7 Parents: 893eed9 Author: Edison Su <[email protected]> Authored: Thu Oct 16 12:51:11 2014 -0700 Committer: Edison Su <[email protected]> Committed: Thu Nov 6 15:29:00 2014 -0800 ---------------------------------------------------------------------- .../kvm/resource/LibvirtComputingResource.java | 26 +++++++++++++++ .../hypervisor/kvm/resource/LibvirtVMDef.java | 35 ++++++++++++++++++++ .../kvm/resource/LibvirtVMDefTest.java | 22 ++++++++++++ 3 files changed, 83 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9319a4e5/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 9a4ae16..55b49c2 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 @@ -454,6 +454,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv protected boolean _noKvmClock; protected String _videoHw; protected int _videoRam; + protected Pair<Integer,Integer> hostOsVersion; private final Map <String, String> _pifs = new HashMap<String, String>(); private final Map<String, VmStats> _vmStats = new ConcurrentHashMap<String, VmStats>(); @@ -965,6 +966,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv String[] kernelVersions = unameKernelVersion.split("[\\.\\-]"); _kernelVersion = Integer.parseInt(kernelVersions[0]) * 1000 * 1000 + Integer.parseInt(kernelVersions[1]) * 1000 + Integer.parseInt(kernelVersions[2]); + getOsVersion(); return true; } @@ -3606,6 +3608,24 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return uuid; } + private void getOsVersion() { + String version = Script.runSimpleBashScript("cat /etc/redhat-release | awk '{print $7}'"); + if (version != null) { + String[] versions = version.split("."); + if (versions.length == 2) { + String major = versions[0]; + String minor = versions[1]; + try { + Integer m = Integer.parseInt(major); + Integer min = Integer.parseInt(minor); + hostOsVersion = new Pair<>(m, min); + } catch(NumberFormatException e) { + + } + } + } + } + protected LibvirtVMDef createVMFromSpec(VirtualMachineTO vmTO) { LibvirtVMDef vm = new LibvirtVMDef(); vm.setDomainName(vmTO.getName()); @@ -3684,6 +3704,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv features.addFeatures("pae"); features.addFeatures("apic"); features.addFeatures("acpi"); + //for rhel 6.5 and above, hyperv enlightment feature is added + if (vmTO.getOs().contains("Windows Server 2008") && hostOsVersion != null && ((hostOsVersion.first() == 6 && hostOsVersion.second() >= 5) || (hostOsVersion.first() >= 7))) { + LibvirtVMDef.HyperVEnlightenmentFeatureDef hyv = new LibvirtVMDef.HyperVEnlightenmentFeatureDef(); + hyv.setRelaxed(true); + features.addHyperVFeature(hyv); + } vm.addComp(features); TermPolicy term = new TermPolicy(); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9319a4e5/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 bc95204..2ce2442 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 @@ -173,13 +173,42 @@ public class LibvirtVMDef { } } + public static class HyperVEnlightenmentFeatureDef { + private final Map<String, String> features = new HashMap<String,String>(); + public void setRelaxed(boolean on) { + String state = on ? "On":"Off"; + features.put("relaxed", state); + } + @Override + public String toString() { + if (features.isEmpty()) { + return ""; + } + StringBuilder feaBuilder = new StringBuilder(); + feaBuilder.append("<hyperv>\n"); + for (Map.Entry<String, String> e : features.entrySet()) { + feaBuilder.append("<"); + feaBuilder.append(e.getKey()); + feaBuilder.append(" state='" + e.getValue() + "'"); + feaBuilder.append("/>\n"); + } + feaBuilder.append("</hyperv>\n"); + return feaBuilder.toString(); + } + } + public static class FeaturesDef { private final List<String> _features = new ArrayList<String>(); + private HyperVEnlightenmentFeatureDef hyperVEnlightenmentFeatureDef = null; public void addFeatures(String feature) { _features.add(feature); } + public void addHyperVFeature(HyperVEnlightenmentFeatureDef hyperVEnlightenmentFeatureDef) { + this.hyperVEnlightenmentFeatureDef = hyperVEnlightenmentFeatureDef; + } + @Override public String toString() { StringBuilder feaBuilder = new StringBuilder(); @@ -187,6 +216,12 @@ public class LibvirtVMDef { for (String feature : _features) { feaBuilder.append("<" + feature + "/>\n"); } + if (hyperVEnlightenmentFeatureDef != null) { + String hpervF = hyperVEnlightenmentFeatureDef.toString(); + if (hpervF != "") { + feaBuilder.append(hpervF); + } + } feaBuilder.append("</features>\n"); return feaBuilder.toString(); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9319a4e5/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 aa7570c..ddbe256 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 @@ -21,6 +21,7 @@ package com.cloud.hypervisor.kvm.resource; import junit.framework.TestCase; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; +import com.cloud.utils.Pair; public class LibvirtVMDefTest extends TestCase { @@ -90,4 +91,25 @@ public class LibvirtVMDefTest extends TestCase { assertEquals(xmlDef, expectedXml); } + public void testHypervEnlightDef() { + LibvirtVMDef.FeaturesDef featuresDef = new LibvirtVMDef.FeaturesDef(); + LibvirtVMDef.HyperVEnlightenmentFeatureDef hyperVEnlightenmentFeatureDef = new LibvirtVMDef.HyperVEnlightenmentFeatureDef(); + hyperVEnlightenmentFeatureDef.setRelaxed(true); + featuresDef.addHyperVFeature(hyperVEnlightenmentFeatureDef); + String defs = featuresDef.toString(); + assertTrue(defs.contains("relaxed")); + + featuresDef = new LibvirtVMDef.FeaturesDef(); + featuresDef.addFeatures("pae"); + defs = featuresDef.toString(); + assertFalse(defs.contains("relaxed")); + + assertTrue("Windows Server 2008 R2".contains("Windows Server 2008")); + + Pair<Integer,Integer> hostOsVersion = new Pair<Integer,Integer>(6,5); + assertTrue((hostOsVersion.first() == 6 && hostOsVersion.second() >= 5) || (hostOsVersion.first() >= 7)); + hostOsVersion = new Pair<Integer,Integer>(7,1); + assertTrue((hostOsVersion.first() == 6 && hostOsVersion.second() >= 5) || (hostOsVersion.first() >= 7)); + } + }
