This is an automated email from the ASF dual-hosted git repository.

rohit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/master by this push:
     new 798b79f  kvm: disable cpu features if feature starts with '-' (#3335)
798b79f is described below

commit 798b79fa5bd8c75af13f425a215618faaec02d89
Author: ustcweizhou <ustcweiz...@gmail.com>
AuthorDate: Mon May 27 15:13:38 2019 +0200

    kvm: disable cpu features if feature starts with '-' (#3335)
    
    When I use SandyBridge as custom cpu in my testing, vm failed to start due 
to following error:
    ```
    org.libvirt.LibvirtException: unsupported configuration: guest and host CPU 
are not compatible: Host CPU does not provide required features: avx, xsave, 
aes, tsc-deadline, x2apic, pclmuldq
    ```
    
    With this patch, it works with the following setting in agent.properties:
    ```
      guest.cpu.mode=custom
      guest.cpu.model=SandyBridge
      guest.cpu.features=-avx -xsave -aes -tsc-deadline -x2apic -pclmuldq
    ```
    
    vm cpu is defined as below:
    ```
      <cpu mode='custom' match='exact'>
        <model fallback='allow'>SandyBridge</model>
        <feature policy='disable' name='avx'/>
        <feature policy='disable' name='xsave'/>
        <feature policy='disable' name='aes'/>
        <feature policy='disable' name='tsc-deadline'/>
        <feature policy='disable' name='x2apic'/>
        <feature policy='disable' name='pclmuldq'/>
      </cpu>
    ```
---
 .../hypervisor/kvm/resource/LibvirtVMDef.java      |  6 ++++-
 .../hypervisor/kvm/resource/LibvirtVMDefTest.java  | 27 ++++++++++++++++++++++
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
index 1b37783..617c278 100644
--- 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
+++ 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
@@ -1360,7 +1360,11 @@ public class LibvirtVMDef {
 
             if (_features != null) {
                 for (String feature : _features) {
-                    modeBuilder.append("<feature policy='require' name='" + 
feature + "'/>");
+                    if (feature.startsWith("-")) {
+                        modeBuilder.append("<feature policy='disable' name='" 
+ feature.substring(1) + "'/>");
+                    } else {
+                        modeBuilder.append("<feature policy='require' name='" 
+ feature + "'/>");
+                    }
                 }
             }
 
diff --git 
a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java
 
b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java
index 7d311e6..b0eaad4 100644
--- 
a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java
+++ 
b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java
@@ -20,6 +20,8 @@
 package com.cloud.hypervisor.kvm.resource;
 
 import java.io.File;
+import java.util.Arrays;
+import java.util.List;
 import java.util.Scanner;
 
 import junit.framework.TestCase;
@@ -140,6 +142,31 @@ public class LibvirtVMDefTest extends TestCase {
     }
 
     @Test
+    public void testCpuModeDefCpuFeatures() {
+        LibvirtVMDef.CpuModeDef cpuModeDef = new LibvirtVMDef.CpuModeDef();
+        cpuModeDef.setMode("custom");
+        cpuModeDef.setModel("Nehalem");
+
+        String expected_start = "<cpu mode='custom' match='exact'><model 
fallback='allow'>Nehalem</model>";
+        String expected_end = "</cpu>";
+
+        List<String> features1 = Arrays.asList("feature1", "feature2");
+        cpuModeDef.setFeatures(features1);
+        String expected1 = "<feature policy='require' 
name='feature1'/><feature policy='require' name='feature2'/>";
+        assertEquals(expected_start + expected1 + expected_end, 
cpuModeDef.toString());
+
+        List<String> features2 = Arrays.asList("-feature1", "-feature2");
+        cpuModeDef.setFeatures(features2);
+        String expected2 = "<feature policy='disable' 
name='feature1'/><feature policy='disable' name='feature2'/>";
+        assertEquals(expected_start + expected2 + expected_end, 
cpuModeDef.toString());
+
+        List<String> features3 = Arrays.asList("-feature1", "feature2");
+        cpuModeDef.setFeatures(features3);
+        String expected3 = "<feature policy='disable' 
name='feature1'/><feature policy='require' name='feature2'/>";
+        assertEquals(expected_start + expected3 + expected_end, 
cpuModeDef.toString());
+    }
+
+    @Test
     public void testDiskDef() {
         String filePath = "/var/lib/libvirt/images/disk.qcow2";
         String diskLabel = "vda";

Reply via email to