]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Store more types in qemuMonitorCPUModelInfo
authorJiri Denemark <jdenemar@redhat.com>
Wed, 22 Feb 2017 15:01:30 +0000 (16:01 +0100)
committerJiri Denemark <jdenemar@redhat.com>
Fri, 3 Mar 2017 18:57:56 +0000 (19:57 +0100)
While query-cpu-model-expansion returns only boolean features on s390,
but x86_64 reports some integer and string properties which we are
interested in.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
src/qemu/qemu_capabilities.c
src/qemu/qemu_monitor.c
src/qemu/qemu_monitor.h
src/qemu/qemu_monitor_json.c
tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml

index 0e9c81b6b0d94714ed81e4dbb49e7864ed946742..d92aa9542864dbd5f66a741bf46d689af93a1590 100644 (file)
@@ -3082,14 +3082,16 @@ virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
     cpu->nfeatures = 0;
 
     for (i = 0; i < modelInfo->nprops; i++) {
-        if (VIR_STRDUP(cpu->features[i].name, modelInfo->props[i].name) < 0)
-            return -1;
+        virCPUFeatureDefPtr feature = cpu->features + cpu->nfeatures;
+        qemuMonitorCPUPropertyPtr prop = modelInfo->props + i;
 
-        if (modelInfo->props[i].supported)
-            cpu->features[i].policy = VIR_CPU_FEATURE_REQUIRE;
-        else
-            cpu->features[i].policy = VIR_CPU_FEATURE_DISABLE;
+        if (prop->type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN)
+            continue;
 
+        if (VIR_STRDUP(feature->name, prop->name) < 0)
+            return -1;
+        feature->policy = prop->value.boolean ? VIR_CPU_FEATURE_REQUIRE
+                                              : VIR_CPU_FEATURE_DISABLE;
         cpu->nfeatures++;
     }
 
@@ -3195,30 +3197,59 @@ virQEMUCapsLoadHostCPUModelInfo(virQEMUCapsPtr qemuCaps,
         hostCPU->nprops = n;
 
         for (i = 0; i < n; i++) {
-            hostCPU->props[i].name = virXMLPropString(nodes[i], "name");
-            if (!hostCPU->props[i].name) {
+            qemuMonitorCPUPropertyPtr prop = hostCPU->props + i;
+            int type;
+
+            ctxt->node = nodes[i];
+
+            if (!(prop->name = virXMLPropString(ctxt->node, "name"))) {
                 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                _("missing 'name' attribute for a host CPU"
                                  " model property in QEMU capabilities cache"));
                 goto cleanup;
             }
 
-            if (!(str = virXMLPropString(nodes[i], "value"))) {
+            if (!(str = virXMLPropString(ctxt->node, "type")) ||
+                (type = qemuMonitorCPUPropertyTypeFromString(str)) < 0) {
                 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                               _("missing 'value' attribute for a host CPU"
-                                 " model property in QEMU capabilities cache"));
-                goto cleanup;
-            }
-            if (STREQ(str, "true")) {
-                hostCPU->props[i].supported = true;
-            } else if (STREQ(str, "false")) {
-                hostCPU->props[i].supported = false;
-            } else {
-                virReportError(VIR_ERR_INTERNAL_ERROR,
-                               _("invalid boolean  value: '%s'"), str);
+                               _("missing or invalid CPU model property type "
+                                 "in QEMU capabilities cache"));
                 goto cleanup;
             }
             VIR_FREE(str);
+
+            prop->type = type;
+            switch (prop->type) {
+            case QEMU_MONITOR_CPU_PROPERTY_BOOLEAN:
+                if (virXPathBoolean("./@value='true'", ctxt))
+                    prop->value.boolean = true;
+                break;
+
+            case QEMU_MONITOR_CPU_PROPERTY_STRING:
+                prop->value.string = virXMLPropString(ctxt->node, "value");
+                if (!prop->value.string) {
+                    virReportError(VIR_ERR_INTERNAL_ERROR,
+                                   _("invalid string value for '%s' host CPU "
+                                     "model property in QEMU capabilities cache"),
+                                   prop->name);
+                    goto cleanup;
+                }
+                break;
+
+            case QEMU_MONITOR_CPU_PROPERTY_NUMBER:
+                if (virXPathLongLong("string(./@value)", ctxt,
+                                     &prop->value.number) < 0) {
+                    virReportError(VIR_ERR_INTERNAL_ERROR,
+                                   _("invalid number value for '%s' host CPU "
+                                     "model property in QEMU capabilities cache"),
+                                   prop->name);
+                    goto cleanup;
+                }
+                break;
+
+            case QEMU_MONITOR_CPU_PROPERTY_LAST:
+                break;
+            }
         }
     }
 
@@ -3560,9 +3591,30 @@ virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsPtr qemuCaps,
     virBufferAdjustIndent(buf, 2);
 
     for (i = 0; i < model->nprops; i++) {
-        virBufferAsprintf(buf, "<property name='%s' type='boolean' value='%s'/>\n",
-                          model->props[i].name,
-                          model->props[i].supported ? "true" : "false");
+        qemuMonitorCPUPropertyPtr prop = model->props + i;
+
+        virBufferAsprintf(buf, "<property name='%s' type='%s' ",
+                          prop->name,
+                          qemuMonitorCPUPropertyTypeToString(prop->type));
+
+        switch (prop->type) {
+        case QEMU_MONITOR_CPU_PROPERTY_BOOLEAN:
+            virBufferAsprintf(buf, "value='%s'",
+                              prop->value.boolean ? "true" : "false");
+            break;
+
+        case QEMU_MONITOR_CPU_PROPERTY_STRING:
+            virBufferEscapeString(buf, "value='%s'", prop->value.string);
+            break;
+
+        case QEMU_MONITOR_CPU_PROPERTY_NUMBER:
+            virBufferAsprintf(buf, "value='%lld'", prop->value.number);
+            break;
+
+        case QEMU_MONITOR_CPU_PROPERTY_LAST:
+            break;
+        }
+        virBufferAddLit(buf, "/>\n");
     }
 
     virBufferAdjustIndent(buf, -2);
index b15207a693d9f44babec5dcb3880ef43c8f61fde..4c3f7a20fe0169e09ed931f25d59565605fd211f 100644 (file)
@@ -3661,8 +3661,11 @@ qemuMonitorCPUModelInfoFree(qemuMonitorCPUModelInfoPtr model_info)
     if (!model_info)
         return;
 
-    for (i = 0; i < model_info->nprops; i++)
+    for (i = 0; i < model_info->nprops; i++) {
         VIR_FREE(model_info->props[i].name);
+        if (model_info->props[i].type == QEMU_MONITOR_CPU_PROPERTY_STRING)
+            VIR_FREE(model_info->props[i].value.string);
+    }
 
     VIR_FREE(model_info->props);
     VIR_FREE(model_info->name);
@@ -3691,7 +3694,25 @@ qemuMonitorCPUModelInfoCopy(const qemuMonitorCPUModelInfo *orig)
         if (VIR_STRDUP(copy->props[i].name, orig->props[i].name) < 0)
             goto error;
 
-        copy->props[i].supported = orig->props[i].supported;
+        copy->props[i].type = orig->props[i].type;
+        switch (orig->props[i].type) {
+        case QEMU_MONITOR_CPU_PROPERTY_BOOLEAN:
+            copy->props[i].value.boolean = orig->props[i].value.boolean;
+            break;
+
+        case QEMU_MONITOR_CPU_PROPERTY_STRING:
+            if (VIR_STRDUP(copy->props[i].value.string,
+                           orig->props[i].value.string) < 0)
+                goto error;
+            break;
+
+        case QEMU_MONITOR_CPU_PROPERTY_NUMBER:
+            copy->props[i].value.number = orig->props[i].value.number;
+            break;
+
+        case QEMU_MONITOR_CPU_PROPERTY_LAST:
+            break;
+        }
     }
 
     return copy;
index 8811d8501737af459088dbc53e8fb5394632c785..20d59b052dc6be83a09e5c898bdbcf57033864c6 100644 (file)
@@ -921,16 +921,35 @@ int qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon,
                                  qemuMonitorCPUDefInfoPtr **cpus);
 void qemuMonitorCPUDefInfoFree(qemuMonitorCPUDefInfoPtr cpu);
 
+typedef enum {
+    QEMU_MONITOR_CPU_PROPERTY_BOOLEAN,
+    QEMU_MONITOR_CPU_PROPERTY_STRING,
+    QEMU_MONITOR_CPU_PROPERTY_NUMBER,
+
+    QEMU_MONITOR_CPU_PROPERTY_LAST
+} qemuMonitorCPUPropertyType;
+
+VIR_ENUM_DECL(qemuMonitorCPUProperty)
+
+typedef struct _qemuMonitorCPUProperty qemuMonitorCPUProperty;
+typedef qemuMonitorCPUProperty *qemuMonitorCPUPropertyPtr;
+struct _qemuMonitorCPUProperty {
+    char *name;
+    qemuMonitorCPUPropertyType type;
+    union {
+        bool boolean;
+        char *string;
+        long long number;
+    } value;
+};
+
 typedef struct _qemuMonitorCPUModelInfo qemuMonitorCPUModelInfo;
 typedef qemuMonitorCPUModelInfo *qemuMonitorCPUModelInfoPtr;
 
 struct _qemuMonitorCPUModelInfo {
     char *name;
     size_t nprops;
-    struct {
-        char *name;
-        bool supported;
-    } *props;
+    qemuMonitorCPUPropertyPtr props;
 };
 
 int qemuMonitorGetCPUModelExpansion(qemuMonitorPtr mon,
index 69fe340bede553be8c68e287ad4bfb55fca6af8f..e3bef3eb64dd80a8786d812781a7a0f143053b58 100644 (file)
@@ -4977,24 +4977,50 @@ qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
     return ret;
 }
 
+
+VIR_ENUM_IMPL(qemuMonitorCPUProperty,
+              QEMU_MONITOR_CPU_PROPERTY_LAST,
+              "boolean", "string", "number")
+
 static int
 qemuMonitorJSONParseCPUModelProperty(const char *key,
                                      virJSONValue *value,
                                      void *opaque)
 {
     qemuMonitorCPUModelInfoPtr machine_model = opaque;
-    size_t n = machine_model->nprops;
-    bool supported;
+    qemuMonitorCPUPropertyPtr prop;
 
-    if (virJSONValueGetBoolean(value, &supported) < 0)
-        return 0;
+    prop = machine_model->props + machine_model->nprops;
 
-    if (VIR_STRDUP(machine_model->props[n].name, key) < 0)
-        return -1;
+    switch ((virJSONType) value->type) {
+    case VIR_JSON_TYPE_STRING:
+        if (VIR_STRDUP(prop->value.string, virJSONValueGetString(value)) < 0)
+            return -1;
+        prop->type = QEMU_MONITOR_CPU_PROPERTY_STRING;
+        break;
+
+    case VIR_JSON_TYPE_NUMBER:
+        /* Ignore numbers which cannot be parsed as unsigned long long */
+        if (virJSONValueGetNumberLong(value, &prop->value.number) < 0)
+            return 0;
+        prop->type = QEMU_MONITOR_CPU_PROPERTY_NUMBER;
+        break;
 
-    machine_model->props[n].supported = supported;
+    case VIR_JSON_TYPE_BOOLEAN:
+        virJSONValueGetBoolean(value, &prop->value.boolean);
+        prop->type = QEMU_MONITOR_CPU_PROPERTY_BOOLEAN;
+        break;
+
+    case VIR_JSON_TYPE_OBJECT:
+    case VIR_JSON_TYPE_ARRAY:
+    case VIR_JSON_TYPE_NULL:
+        return 0;
+    }
 
     machine_model->nprops++;
+    if (VIR_STRDUP(prop->name, key) < 0)
+        return -1;
+
     return 0;
 }
 
index 64da511c78040ffd4bc0d7b3fb69ff161d3bdb1b..3cce40c6887ad97b9452fe2408822bc940f6f020 100644 (file)
     <property name='avx512cd' type='boolean' value='false'/>
     <property name='decodeassists' type='boolean' value='false'/>
     <property name='sse4.1' type='boolean' value='true'/>
+    <property name='family' type='number' value='6'/>
     <property name='avx512f' type='boolean' value='false'/>
     <property name='msr' type='boolean' value='true'/>
     <property name='mce' type='boolean' value='true'/>
     <property name='mca' type='boolean' value='true'/>
     <property name='xcrypt' type='boolean' value='false'/>
+    <property name='min-level' type='number' value='13'/>
     <property name='xgetbv1' type='boolean' value='true'/>
     <property name='cid' type='boolean' value='false'/>
     <property name='ds' type='boolean' value='false'/>
     <property name='xcrypt-en' type='boolean' value='false'/>
     <property name='pn' type='boolean' value='false'/>
     <property name='dca' type='boolean' value='false'/>
+    <property name='vendor' type='string' value='GenuineIntel'/>
     <property name='pku' type='boolean' value='false'/>
     <property name='smx' type='boolean' value='false'/>
     <property name='cmp-legacy' type='boolean' value='false'/>
     <property name='sse4.2' type='boolean' value='true'/>
     <property name='pge' type='boolean' value='true'/>
     <property name='pdcm' type='boolean' value='false'/>
+    <property name='model' type='number' value='94'/>
     <property name='movbe' type='boolean' value='true'/>
     <property name='nrip-save' type='boolean' value='false'/>
     <property name='ssse3' type='boolean' value='true'/>
     <property name='fma' type='boolean' value='true'/>
     <property name='cx16' type='boolean' value='true'/>
     <property name='de' type='boolean' value='true'/>
+    <property name='stepping' type='number' value='3'/>
     <property name='xsave' type='boolean' value='true'/>
     <property name='clflush' type='boolean' value='true'/>
     <property name='skinit' type='boolean' value='false'/>
     <property name='sep' type='boolean' value='true'/>
     <property name='nodeid-msr' type='boolean' value='false'/>
     <property name='misalignsse' type='boolean' value='false'/>
+    <property name='min-xlevel' type='number' value='2147483656'/>
     <property name='bmi1' type='boolean' value='true'/>
     <property name='bmi2' type='boolean' value='true'/>
     <property name='kvm-pv-unhalt' type='boolean' value='true'/>
     <property name='pse36' type='boolean' value='true'/>
     <property name='tbm' type='boolean' value='false'/>
     <property name='wdt' type='boolean' value='false'/>
+    <property name='model-id' type='string' value='Intel(R) Xeon(R) CPU E3-1245 v5 @ 3.50GHz'/>
     <property name='sha-ni' type='boolean' value='false'/>
     <property name='abm' type='boolean' value='true'/>
     <property name='avx512pf' type='boolean' value='false'/>