[libvirt] [PATCH v2 31/31] qemu: Add support for unavailable-features

Jiri Denemark jdenemar at redhat.com
Sun Nov 20 23:21:27 UTC 2016


QEMU 2.8.0 adds support for unavailable-features in
query-cpu-definitions reply. The unavailable-features array lists CPU
features which prevent a corresponding CPU model from being usable on
current host. It can only be used when all the unavailable features are
disabled. Empty array means the CPU model can be used without
modifications.

We can use unavailable-features for providing CPU model usability info
in domain capabilities XML:

    <domainCapabilities>
      ...
      <cpu>
        <mode name='host-passthrough' supported='yes'/>
        <mode name='host-model' supported='yes'>
          <model fallback='allow'>Skylake-Client</model>
          ...
        </mode>
        <mode name='custom' supported='yes'>
          <model usable='yes'>qemu64</model>
          <model usable='yes'>qemu32</model>
          <model usable='no'>phenom</model>
          <model usable='yes'>pentium3</model>
          <model usable='yes'>pentium2</model>
          <model usable='yes'>pentium</model>
          <model usable='yes'>n270</model>
          <model usable='yes'>kvm64</model>
          <model usable='yes'>kvm32</model>
          <model usable='yes'>coreduo</model>
          <model usable='yes'>core2duo</model>
          <model usable='no'>athlon</model>
          <model usable='yes'>Westmere</model>
          <model usable='yes'>Skylake-Client</model>
          ...
        </mode>
      </cpu>
      ...
    </domainCapabilities>

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 src/qemu/qemu_capabilities.c                       |  39 +++++--
 src/qemu/qemu_capabilities.h                       |   3 +-
 src/qemu/qemu_monitor.h                            |   1 +
 src/qemu/qemu_monitor_json.c                       |  18 ++++
 .../domaincapsschemadata/qemu_2.8.0-tcg.x86_64.xml |  58 +++++-----
 tests/domaincapsschemadata/qemu_2.8.0.x86_64.xml   |  58 +++++-----
 tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml   | 120 ++++++++++-----------
 tests/qemumonitorjsontest.c                        |  27 ++++-
 tests/qemuxml2argvtest.c                           |  24 +++--
 9 files changed, 207 insertions(+), 141 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 54253cb..bfeee25 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2346,7 +2346,8 @@ int
 virQEMUCapsAddCPUDefinitions(virQEMUCapsPtr qemuCaps,
                              virDomainVirtType type,
                              const char **name,
-                             size_t count)
+                             size_t count,
+                             virDomainCapsCPUUsable usable)
 {
     size_t i;
     virDomainCapsCPUModelsPtr cpus = NULL;
@@ -2367,8 +2368,7 @@ virQEMUCapsAddCPUDefinitions(virQEMUCapsPtr qemuCaps,
     }
 
     for (i = 0; i < count; i++) {
-        if (virDomainCapsCPUModelsAdd(cpus, name[i], -1,
-                                      VIR_DOMCAPS_CPU_USABLE_UNKNOWN) < 0)
+        if (virDomainCapsCPUModelsAdd(cpus, name[i], -1, usable) < 0)
             return -1;
     }
 
@@ -2784,9 +2784,14 @@ virQEMUCapsProbeQMPCPUDefinitions(virQEMUCapsPtr qemuCaps,
         qemuCaps->kvmCPUModels = models;
 
     for (i = 0; i < ncpus; i++) {
-        if (virDomainCapsCPUModelsAddSteal(models,
-                                           &cpus[i]->name,
-                                           VIR_DOMCAPS_CPU_USABLE_UNKNOWN) < 0)
+        virDomainCapsCPUUsable usable = VIR_DOMCAPS_CPU_USABLE_UNKNOWN;
+
+        if (cpus[i]->usable == VIR_TRISTATE_BOOL_YES)
+            usable = VIR_DOMCAPS_CPU_USABLE_YES;
+        else if (cpus[i]->usable == VIR_TRISTATE_BOOL_NO)
+            usable = VIR_DOMCAPS_CPU_USABLE_NO;
+
+        if (virDomainCapsCPUModelsAddSteal(models, &cpus[i]->name, usable) < 0)
             goto cleanup;
     }
 
@@ -3097,14 +3102,23 @@ virQEMUCapsLoadCPUModels(virQEMUCapsPtr qemuCaps,
         qemuCaps->tcgCPUModels = cpus;
 
     for (i = 0; i < n; i++) {
+        int usable = VIR_DOMCAPS_CPU_USABLE_UNKNOWN;
+
+        if ((str = virXMLPropString(nodes[i], "usable")) &&
+            (usable = virDomainCapsCPUUsableTypeFromString(str)) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("unknown value '%s' in attribute 'usable'"), str);
+            goto cleanup;
+        }
+        VIR_FREE(str);
+
         if (!(str = virXMLPropString(nodes[i], "name"))) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("missing cpu name in QEMU capabilities cache"));
             goto cleanup;
         }
 
-        if (virDomainCapsCPUModelsAddSteal(cpus, &str,
-                                           VIR_DOMCAPS_CPU_USABLE_UNKNOWN) < 0)
+        if (virDomainCapsCPUModelsAddSteal(cpus, &str, usable) < 0)
             goto cleanup;
     }
 
@@ -3383,8 +3397,15 @@ virQEMUCapsFormatCPUModels(virQEMUCapsPtr qemuCaps,
         return;
 
     for (i = 0; i < cpus->nmodels; i++) {
+        virDomainCapsCPUModelPtr cpu = cpus->models + i;
+
         virBufferAsprintf(buf, "<cpu type='%s' ", typeStr);
-        virBufferEscapeString(buf, "name='%s'/>\n", cpus->models[i].name);
+        virBufferEscapeString(buf, "name='%s'", cpu->name);
+        if (cpu->usable) {
+            virBufferAsprintf(buf, " usable='%s'",
+                              virDomainCapsCPUUsableTypeToString(cpu->usable));
+        }
+        virBufferAddLit(buf, "/>\n");
     }
 }
 
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 2f24452..5fa7c5a 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -432,7 +432,8 @@ unsigned int virQEMUCapsGetKVMVersion(virQEMUCapsPtr qemuCaps);
 int virQEMUCapsAddCPUDefinitions(virQEMUCapsPtr qemuCaps,
                                  virDomainVirtType type,
                                  const char **name,
-                                 size_t count);
+                                 size_t count,
+                                 virDomainCapsCPUUsable usable);
 int virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps,
                                  virDomainVirtType type,
                                  char ***names,
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index a0e5075..a94c8be 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -913,6 +913,7 @@ typedef struct _qemuMonitorCPUDefInfo qemuMonitorCPUDefInfo;
 typedef qemuMonitorCPUDefInfo *qemuMonitorCPUDefInfoPtr;
 
 struct _qemuMonitorCPUDefInfo {
+    virTristateBool usable;
     char *name;
 };
 
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 9e06a4d..c070a9b 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -4958,6 +4958,24 @@ qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
 
         if (VIR_STRDUP(cpu->name, tmp) < 0)
             goto cleanup;
+
+        if (virJSONValueObjectHasKey(child, "unavailable-features")) {
+            virJSONValuePtr blockers;
+
+            blockers = virJSONValueObjectGetArray(child,
+                                                  "unavailable-features");
+            if (!blockers) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("unavailable-features in query-cpu-definitions "
+                                 "reply data was not an array"));
+                goto cleanup;
+            }
+
+            if (virJSONValueArraySize(blockers) > 0)
+                cpu->usable = VIR_TRISTATE_BOOL_NO;
+            else
+                cpu->usable = VIR_TRISTATE_BOOL_YES;
+        }
     }
 
     ret = n;
diff --git a/tests/domaincapsschemadata/qemu_2.8.0-tcg.x86_64.xml b/tests/domaincapsschemadata/qemu_2.8.0-tcg.x86_64.xml
index fe598e9..dd92853 100644
--- a/tests/domaincapsschemadata/qemu_2.8.0-tcg.x86_64.xml
+++ b/tests/domaincapsschemadata/qemu_2.8.0-tcg.x86_64.xml
@@ -24,35 +24,35 @@
       <model fallback='allow'>Broadwell</model>
     </mode>
     <mode name='custom' supported='yes'>
-      <model usable='unknown'>qemu64</model>
-      <model usable='unknown'>qemu32</model>
-      <model usable='unknown'>phenom</model>
-      <model usable='unknown'>pentium3</model>
-      <model usable='unknown'>pentium2</model>
-      <model usable='unknown'>pentium</model>
-      <model usable='unknown'>n270</model>
-      <model usable='unknown'>kvm64</model>
-      <model usable='unknown'>kvm32</model>
-      <model usable='unknown'>coreduo</model>
-      <model usable='unknown'>core2duo</model>
-      <model usable='unknown'>athlon</model>
-      <model usable='unknown'>Westmere</model>
-      <model usable='unknown'>Skylake-Client</model>
-      <model usable='unknown'>SandyBridge</model>
-      <model usable='unknown'>Penryn</model>
-      <model usable='unknown'>Opteron_G5</model>
-      <model usable='unknown'>Opteron_G4</model>
-      <model usable='unknown'>Opteron_G3</model>
-      <model usable='unknown'>Opteron_G2</model>
-      <model usable='unknown'>Opteron_G1</model>
-      <model usable='unknown'>Nehalem</model>
-      <model usable='unknown'>IvyBridge</model>
-      <model usable='unknown'>Haswell</model>
-      <model usable='unknown'>Haswell-noTSX</model>
-      <model usable='unknown'>Conroe</model>
-      <model usable='unknown'>Broadwell</model>
-      <model usable='unknown'>Broadwell-noTSX</model>
-      <model usable='unknown'>486</model>
+      <model usable='yes'>qemu64</model>
+      <model usable='yes'>qemu32</model>
+      <model usable='no'>phenom</model>
+      <model usable='yes'>pentium3</model>
+      <model usable='yes'>pentium2</model>
+      <model usable='yes'>pentium</model>
+      <model usable='yes'>n270</model>
+      <model usable='yes'>kvm64</model>
+      <model usable='yes'>kvm32</model>
+      <model usable='yes'>coreduo</model>
+      <model usable='yes'>core2duo</model>
+      <model usable='yes'>athlon</model>
+      <model usable='yes'>Westmere</model>
+      <model usable='no'>Skylake-Client</model>
+      <model usable='no'>SandyBridge</model>
+      <model usable='yes'>Penryn</model>
+      <model usable='no'>Opteron_G5</model>
+      <model usable='no'>Opteron_G4</model>
+      <model usable='no'>Opteron_G3</model>
+      <model usable='yes'>Opteron_G2</model>
+      <model usable='yes'>Opteron_G1</model>
+      <model usable='yes'>Nehalem</model>
+      <model usable='no'>IvyBridge</model>
+      <model usable='no'>Haswell</model>
+      <model usable='no'>Haswell-noTSX</model>
+      <model usable='yes'>Conroe</model>
+      <model usable='no'>Broadwell</model>
+      <model usable='no'>Broadwell-noTSX</model>
+      <model usable='yes'>486</model>
     </mode>
   </cpu>
   <devices>
diff --git a/tests/domaincapsschemadata/qemu_2.8.0.x86_64.xml b/tests/domaincapsschemadata/qemu_2.8.0.x86_64.xml
index 7b8f90e..4c5fffc 100644
--- a/tests/domaincapsschemadata/qemu_2.8.0.x86_64.xml
+++ b/tests/domaincapsschemadata/qemu_2.8.0.x86_64.xml
@@ -24,35 +24,35 @@
       <model fallback='allow'>Broadwell</model>
     </mode>
     <mode name='custom' supported='yes'>
-      <model usable='unknown'>qemu64</model>
-      <model usable='unknown'>qemu32</model>
-      <model usable='unknown'>phenom</model>
-      <model usable='unknown'>pentium3</model>
-      <model usable='unknown'>pentium2</model>
-      <model usable='unknown'>pentium</model>
-      <model usable='unknown'>n270</model>
-      <model usable='unknown'>kvm64</model>
-      <model usable='unknown'>kvm32</model>
-      <model usable='unknown'>coreduo</model>
-      <model usable='unknown'>core2duo</model>
-      <model usable='unknown'>athlon</model>
-      <model usable='unknown'>Westmere</model>
-      <model usable='unknown'>Skylake-Client</model>
-      <model usable='unknown'>SandyBridge</model>
-      <model usable='unknown'>Penryn</model>
-      <model usable='unknown'>Opteron_G5</model>
-      <model usable='unknown'>Opteron_G4</model>
-      <model usable='unknown'>Opteron_G3</model>
-      <model usable='unknown'>Opteron_G2</model>
-      <model usable='unknown'>Opteron_G1</model>
-      <model usable='unknown'>Nehalem</model>
-      <model usable='unknown'>IvyBridge</model>
-      <model usable='unknown'>Haswell</model>
-      <model usable='unknown'>Haswell-noTSX</model>
-      <model usable='unknown'>Conroe</model>
-      <model usable='unknown'>Broadwell</model>
-      <model usable='unknown'>Broadwell-noTSX</model>
-      <model usable='unknown'>486</model>
+      <model usable='yes'>qemu64</model>
+      <model usable='yes'>qemu32</model>
+      <model usable='no'>phenom</model>
+      <model usable='yes'>pentium3</model>
+      <model usable='yes'>pentium2</model>
+      <model usable='yes'>pentium</model>
+      <model usable='yes'>n270</model>
+      <model usable='yes'>kvm64</model>
+      <model usable='yes'>kvm32</model>
+      <model usable='yes'>coreduo</model>
+      <model usable='yes'>core2duo</model>
+      <model usable='no'>athlon</model>
+      <model usable='yes'>Westmere</model>
+      <model usable='yes'>Skylake-Client</model>
+      <model usable='yes'>SandyBridge</model>
+      <model usable='yes'>Penryn</model>
+      <model usable='no'>Opteron_G5</model>
+      <model usable='no'>Opteron_G4</model>
+      <model usable='no'>Opteron_G3</model>
+      <model usable='yes'>Opteron_G2</model>
+      <model usable='yes'>Opteron_G1</model>
+      <model usable='yes'>Nehalem</model>
+      <model usable='yes'>IvyBridge</model>
+      <model usable='yes'>Haswell</model>
+      <model usable='yes'>Haswell-noTSX</model>
+      <model usable='yes'>Conroe</model>
+      <model usable='yes'>Broadwell</model>
+      <model usable='yes'>Broadwell-noTSX</model>
+      <model usable='yes'>486</model>
     </mode>
   </cpu>
   <devices>
diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
index d5f0ab9..8d68515 100644
--- a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
@@ -199,66 +199,66 @@
   <kvmVersion>0</kvmVersion>
   <package> (v2.8.0-rc0-dirty)</package>
   <arch>x86_64</arch>
-  <cpu type='kvm' name='host'/>
-  <cpu type='kvm' name='qemu64'/>
-  <cpu type='kvm' name='qemu32'/>
-  <cpu type='kvm' name='phenom'/>
-  <cpu type='kvm' name='pentium3'/>
-  <cpu type='kvm' name='pentium2'/>
-  <cpu type='kvm' name='pentium'/>
-  <cpu type='kvm' name='n270'/>
-  <cpu type='kvm' name='kvm64'/>
-  <cpu type='kvm' name='kvm32'/>
-  <cpu type='kvm' name='coreduo'/>
-  <cpu type='kvm' name='core2duo'/>
-  <cpu type='kvm' name='athlon'/>
-  <cpu type='kvm' name='Westmere'/>
-  <cpu type='kvm' name='Skylake-Client'/>
-  <cpu type='kvm' name='SandyBridge'/>
-  <cpu type='kvm' name='Penryn'/>
-  <cpu type='kvm' name='Opteron_G5'/>
-  <cpu type='kvm' name='Opteron_G4'/>
-  <cpu type='kvm' name='Opteron_G3'/>
-  <cpu type='kvm' name='Opteron_G2'/>
-  <cpu type='kvm' name='Opteron_G1'/>
-  <cpu type='kvm' name='Nehalem'/>
-  <cpu type='kvm' name='IvyBridge'/>
-  <cpu type='kvm' name='Haswell'/>
-  <cpu type='kvm' name='Haswell-noTSX'/>
-  <cpu type='kvm' name='Conroe'/>
-  <cpu type='kvm' name='Broadwell'/>
-  <cpu type='kvm' name='Broadwell-noTSX'/>
-  <cpu type='kvm' name='486'/>
-  <cpu type='tcg' name='host'/>
-  <cpu type='tcg' name='qemu64'/>
-  <cpu type='tcg' name='qemu32'/>
-  <cpu type='tcg' name='phenom'/>
-  <cpu type='tcg' name='pentium3'/>
-  <cpu type='tcg' name='pentium2'/>
-  <cpu type='tcg' name='pentium'/>
-  <cpu type='tcg' name='n270'/>
-  <cpu type='tcg' name='kvm64'/>
-  <cpu type='tcg' name='kvm32'/>
-  <cpu type='tcg' name='coreduo'/>
-  <cpu type='tcg' name='core2duo'/>
-  <cpu type='tcg' name='athlon'/>
-  <cpu type='tcg' name='Westmere'/>
-  <cpu type='tcg' name='Skylake-Client'/>
-  <cpu type='tcg' name='SandyBridge'/>
-  <cpu type='tcg' name='Penryn'/>
-  <cpu type='tcg' name='Opteron_G5'/>
-  <cpu type='tcg' name='Opteron_G4'/>
-  <cpu type='tcg' name='Opteron_G3'/>
-  <cpu type='tcg' name='Opteron_G2'/>
-  <cpu type='tcg' name='Opteron_G1'/>
-  <cpu type='tcg' name='Nehalem'/>
-  <cpu type='tcg' name='IvyBridge'/>
-  <cpu type='tcg' name='Haswell'/>
-  <cpu type='tcg' name='Haswell-noTSX'/>
-  <cpu type='tcg' name='Conroe'/>
-  <cpu type='tcg' name='Broadwell'/>
-  <cpu type='tcg' name='Broadwell-noTSX'/>
-  <cpu type='tcg' name='486'/>
+  <cpu type='kvm' name='host' usable='yes'/>
+  <cpu type='kvm' name='qemu64' usable='yes'/>
+  <cpu type='kvm' name='qemu32' usable='yes'/>
+  <cpu type='kvm' name='phenom' usable='no'/>
+  <cpu type='kvm' name='pentium3' usable='yes'/>
+  <cpu type='kvm' name='pentium2' usable='yes'/>
+  <cpu type='kvm' name='pentium' usable='yes'/>
+  <cpu type='kvm' name='n270' usable='yes'/>
+  <cpu type='kvm' name='kvm64' usable='yes'/>
+  <cpu type='kvm' name='kvm32' usable='yes'/>
+  <cpu type='kvm' name='coreduo' usable='yes'/>
+  <cpu type='kvm' name='core2duo' usable='yes'/>
+  <cpu type='kvm' name='athlon' usable='no'/>
+  <cpu type='kvm' name='Westmere' usable='yes'/>
+  <cpu type='kvm' name='Skylake-Client' usable='yes'/>
+  <cpu type='kvm' name='SandyBridge' usable='yes'/>
+  <cpu type='kvm' name='Penryn' usable='yes'/>
+  <cpu type='kvm' name='Opteron_G5' usable='no'/>
+  <cpu type='kvm' name='Opteron_G4' usable='no'/>
+  <cpu type='kvm' name='Opteron_G3' usable='no'/>
+  <cpu type='kvm' name='Opteron_G2' usable='yes'/>
+  <cpu type='kvm' name='Opteron_G1' usable='yes'/>
+  <cpu type='kvm' name='Nehalem' usable='yes'/>
+  <cpu type='kvm' name='IvyBridge' usable='yes'/>
+  <cpu type='kvm' name='Haswell' usable='yes'/>
+  <cpu type='kvm' name='Haswell-noTSX' usable='yes'/>
+  <cpu type='kvm' name='Conroe' usable='yes'/>
+  <cpu type='kvm' name='Broadwell' usable='yes'/>
+  <cpu type='kvm' name='Broadwell-noTSX' usable='yes'/>
+  <cpu type='kvm' name='486' usable='yes'/>
+  <cpu type='tcg' name='host' usable='no'/>
+  <cpu type='tcg' name='qemu64' usable='yes'/>
+  <cpu type='tcg' name='qemu32' usable='yes'/>
+  <cpu type='tcg' name='phenom' usable='no'/>
+  <cpu type='tcg' name='pentium3' usable='yes'/>
+  <cpu type='tcg' name='pentium2' usable='yes'/>
+  <cpu type='tcg' name='pentium' usable='yes'/>
+  <cpu type='tcg' name='n270' usable='yes'/>
+  <cpu type='tcg' name='kvm64' usable='yes'/>
+  <cpu type='tcg' name='kvm32' usable='yes'/>
+  <cpu type='tcg' name='coreduo' usable='yes'/>
+  <cpu type='tcg' name='core2duo' usable='yes'/>
+  <cpu type='tcg' name='athlon' usable='yes'/>
+  <cpu type='tcg' name='Westmere' usable='yes'/>
+  <cpu type='tcg' name='Skylake-Client' usable='no'/>
+  <cpu type='tcg' name='SandyBridge' usable='no'/>
+  <cpu type='tcg' name='Penryn' usable='yes'/>
+  <cpu type='tcg' name='Opteron_G5' usable='no'/>
+  <cpu type='tcg' name='Opteron_G4' usable='no'/>
+  <cpu type='tcg' name='Opteron_G3' usable='no'/>
+  <cpu type='tcg' name='Opteron_G2' usable='yes'/>
+  <cpu type='tcg' name='Opteron_G1' usable='yes'/>
+  <cpu type='tcg' name='Nehalem' usable='yes'/>
+  <cpu type='tcg' name='IvyBridge' usable='no'/>
+  <cpu type='tcg' name='Haswell' usable='no'/>
+  <cpu type='tcg' name='Haswell-noTSX' usable='no'/>
+  <cpu type='tcg' name='Conroe' usable='yes'/>
+  <cpu type='tcg' name='Broadwell' usable='no'/>
+  <cpu type='tcg' name='Broadwell-noTSX' usable='no'/>
+  <cpu type='tcg' name='486' usable='yes'/>
   <machine name='pc-i440fx-2.8' alias='pc' hotplugCpus='yes' maxCpus='255'/>
   <machine name='pc-0.12' hotplugCpus='yes' maxCpus='255'/>
   <machine name='pc-i440fx-2.4' hotplugCpus='yes' maxCpus='255'/>
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index 9f889a9..8bcea93 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -432,10 +432,12 @@ testQemuMonitorJSONGetCPUDefinitions(const void *data)
                                "     \"name\": \"qemu64\" "
                                "   }, "
                                "   { "
-                               "     \"name\": \"Opteron_G4\" "
+                               "     \"name\": \"Opteron_G4\", "
+                               "     \"unavailable-features\": [\"vme\"]"
                                "   }, "
                                "   { "
-                               "     \"name\": \"Westmere\" "
+                               "     \"name\": \"Westmere\", "
+                               "     \"unavailable-features\": []"
                                "   } "
                                "  ]"
                                "}") < 0)
@@ -451,7 +453,7 @@ testQemuMonitorJSONGetCPUDefinitions(const void *data)
         goto cleanup;
     }
 
-#define CHECK(i, wantname)                                              \
+#define CHECK_FULL(i, wantname, Usable)                                 \
     do {                                                                \
         if (STRNEQ(cpus[i]->name, (wantname))) {                        \
             virReportError(VIR_ERR_INTERNAL_ERROR,                      \
@@ -459,13 +461,28 @@ testQemuMonitorJSONGetCPUDefinitions(const void *data)
                            cpus[i]->name, (wantname));                  \
             goto cleanup;                                               \
         }                                                               \
+        if (cpus[i]->usable != (Usable)) {                              \
+            virReportError(VIR_ERR_INTERNAL_ERROR,                      \
+                           "%s: expecting usable flag %d, got %d",      \
+                           cpus[i]->name, Usable, cpus[i]->usable);     \
+            goto cleanup;                                               \
+        }                                                               \
     } while (0)
 
+#define CHECK(i, wantname)                                              \
+    CHECK_FULL(i, wantname, VIR_TRISTATE_BOOL_ABSENT)
+
+#define CHECK_USABLE(i, wantname, usable)                               \
+    CHECK_FULL(i, wantname,                                             \
+               usable ? VIR_TRISTATE_BOOL_YES : VIR_TRISTATE_BOOL_NO)
+
     CHECK(0, "qemu64");
-    CHECK(1, "Opteron_G4");
-    CHECK(2, "Westmere");
+    CHECK_USABLE(1, "Opteron_G4", false);
+    CHECK_USABLE(2, "Westmere", true);
 
 #undef CHECK
+#undef CHECK_USABLE
+#undef CHECK_FULL
 
     ret = 0;
 
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index e44912d..754f46e 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -303,31 +303,39 @@ testAddCPUModels(virQEMUCapsPtr caps, bool skipLegacy)
 
     if (ARCH_IS_X86(arch)) {
         if (virQEMUCapsAddCPUDefinitions(caps, VIR_DOMAIN_VIRT_KVM, x86Models,
-                                         ARRAY_CARDINALITY(x86Models)) < 0 ||
+                                         ARRAY_CARDINALITY(x86Models),
+                                         VIR_DOMCAPS_CPU_USABLE_UNKNOWN) < 0 ||
             virQEMUCapsAddCPUDefinitions(caps, VIR_DOMAIN_VIRT_QEMU, x86Models,
-                                         ARRAY_CARDINALITY(x86Models)) < 0)
+                                         ARRAY_CARDINALITY(x86Models),
+                                         VIR_DOMCAPS_CPU_USABLE_UNKNOWN) < 0)
             return -1;
 
         if (!skipLegacy) {
             if (virQEMUCapsAddCPUDefinitions(caps, VIR_DOMAIN_VIRT_KVM,
                                              x86LegacyModels,
-                                             ARRAY_CARDINALITY(x86LegacyModels)) < 0 ||
+                                             ARRAY_CARDINALITY(x86LegacyModels),
+                                             VIR_DOMCAPS_CPU_USABLE_UNKNOWN) < 0 ||
                 virQEMUCapsAddCPUDefinitions(caps, VIR_DOMAIN_VIRT_QEMU,
                                              x86LegacyModels,
-                                             ARRAY_CARDINALITY(x86LegacyModels)) < 0)
+                                             ARRAY_CARDINALITY(x86LegacyModels),
+                                             VIR_DOMCAPS_CPU_USABLE_UNKNOWN) < 0)
                 return -1;
         }
     } else if (ARCH_IS_ARM(arch)) {
         if (virQEMUCapsAddCPUDefinitions(caps, VIR_DOMAIN_VIRT_KVM, armModels,
-                                         ARRAY_CARDINALITY(armModels)) < 0 ||
+                                         ARRAY_CARDINALITY(armModels),
+                                         VIR_DOMCAPS_CPU_USABLE_UNKNOWN) < 0 ||
             virQEMUCapsAddCPUDefinitions(caps, VIR_DOMAIN_VIRT_QEMU, armModels,
-                                         ARRAY_CARDINALITY(armModels)) < 0)
+                                         ARRAY_CARDINALITY(armModels),
+                                         VIR_DOMCAPS_CPU_USABLE_UNKNOWN) < 0)
             return -1;
     } else if (ARCH_IS_PPC64(arch)) {
         if (virQEMUCapsAddCPUDefinitions(caps, VIR_DOMAIN_VIRT_KVM, ppc64Models,
-                                         ARRAY_CARDINALITY(ppc64Models)) < 0 ||
+                                         ARRAY_CARDINALITY(ppc64Models),
+                                         VIR_DOMCAPS_CPU_USABLE_UNKNOWN) < 0 ||
             virQEMUCapsAddCPUDefinitions(caps, VIR_DOMAIN_VIRT_QEMU, ppc64Models,
-                                         ARRAY_CARDINALITY(ppc64Models)) < 0)
+                                         ARRAY_CARDINALITY(ppc64Models),
+                                         VIR_DOMCAPS_CPU_USABLE_UNKNOWN) < 0)
             return -1;
     }
 
-- 
2.10.2




More information about the libvir-list mailing list