query-cpu-model-expansion may report an array of deprecated properties. This array is optional, and may not be supported for a particular architecture or reported for a particular CPU model. If the output is present, then capture it and store in a qemuMonitorCPUModelInfo struct for later use. The deprecated features will be retained in qemuCaps->kvm->hostCPU.info and will be stored in the capabilities cache file under the <hostCPU> element using the following format: <deprecatedFeatures> <property name='bpb'/> <property name='csske'/> <property name='cte'/> <property name='te'/> </deprecatedFeatures> At this time the data is only queried, parsed, and cached. The data will be utilized in a subsequent patch. Signed-off-by: Collin Walling <walling@xxxxxxxxxxxxx> --- src/qemu/qemu_capabilities.c | 31 +++++++++++++++++++ src/qemu/qemu_monitor.c | 10 ++++++ src/qemu/qemu_monitor.h | 1 + src/qemu/qemu_monitor_json.c | 18 +++++++++++ .../qemucapabilitiesdata/caps_9.1.0_s390x.xml | 6 ++++ .../qemucapabilitiesdata/caps_9.2.0_s390x.xml | 6 ++++ 6 files changed, 72 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 6b67da30ec..9850ed8458 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -4013,6 +4013,7 @@ virQEMUCapsLoadHostCPUModelInfo(virQEMUCapsAccel *caps, const char *typeStr) { xmlNodePtr hostCPUNode; + xmlNodePtr deprecated_props; g_autofree xmlNodePtr *nodes = NULL; VIR_XPATH_NODE_AUTORESTORE(ctxt) g_autoptr(qemuMonitorCPUModelInfo) hostCPU = NULL; @@ -4105,6 +4106,24 @@ virQEMUCapsLoadHostCPUModelInfo(virQEMUCapsAccel *caps, } } + ctxt->node = hostCPUNode; + + if ((deprecated_props = virXPathNode("./deprecatedFeatures", ctxt))) { + g_autoptr(GPtrArray) props = virXMLNodeGetSubelementList(deprecated_props, NULL); + + hostCPU->deprecated_props = g_new0(char *, props->len); + + for (i = 0; i < props->len; i++) { + xmlNodePtr prop = g_ptr_array_index(props, i); + + if (!(hostCPU->deprecated_props[i] = virXMLPropString(prop, "name"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing 'name' attribute for a host CPU model deprecated property in QEMU capabilities cache")); + return -1; + } + } + } + caps->hostCPU.info = g_steal_pointer(&hostCPU); return 0; } @@ -4837,6 +4856,18 @@ virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsAccel *caps, virBufferAddLit(buf, "/>\n"); } + if (model->deprecated_props) { + virBufferAddLit(buf, "<deprecatedFeatures>\n"); + virBufferAdjustIndent(buf, 2); + + for (i = 0; i < g_strv_length(model->deprecated_props); i++) + virBufferAsprintf(buf, "<property name='%s'/>\n", + model->deprecated_props[i]); + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</deprecatedFeatures>\n"); + } + virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</hostCPU>\n"); } diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index fd888e2468..e5d231a867 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3290,6 +3290,7 @@ qemuMonitorCPUModelInfoFree(qemuMonitorCPUModelInfo *model_info) g_free(model_info->props[i].value.string); } + g_strfreev(model_info->deprecated_props); g_free(model_info->props); g_free(model_info->name); g_free(model_info); @@ -3334,6 +3335,15 @@ qemuMonitorCPUModelInfoCopy(const qemuMonitorCPUModelInfo *orig) } } + if (orig->deprecated_props) { + copy->deprecated_props = g_new0(char *, + g_strv_length(orig->deprecated_props)); + + for (i = 0; i < g_strv_length(orig->deprecated_props); i++) { + copy->deprecated_props[i] = g_strdup(orig->deprecated_props[i]); + } + } + return copy; } diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 4341519cfe..97bc1d9a2c 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -1146,6 +1146,7 @@ struct _qemuMonitorCPUModelInfo { char *name; size_t nprops; qemuMonitorCPUProperty *props; + GStrv deprecated_props; bool migratability; }; diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 7c916efacf..5216284c31 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -5095,6 +5095,7 @@ qemuMonitorJSONParseCPUModelExpansionData(virJSONValue *data, bool fail_no_props, virJSONValue **cpu_model, virJSONValue **cpu_props, + virJSONValue **cpu_deprecated_props, const char **cpu_name) { if (qemuMonitorJSONParseCPUModelData(data, "query-cpu-model-expansion", @@ -5102,6 +5103,12 @@ qemuMonitorJSONParseCPUModelExpansionData(virJSONValue *data, cpu_name) < 0) return -1; + /* + * Unconditionally check for the deprecated-props array, as + * it is not a guarantee response even if QEMU supports it. + */ + *cpu_deprecated_props = virJSONValueObjectGetArray(data, "deprecated-props"); + return 0; } @@ -5109,6 +5116,7 @@ qemuMonitorJSONParseCPUModelExpansionData(virJSONValue *data, static int qemuMonitorJSONParseCPUModelExpansion(const char *cpu_name, virJSONValue *cpu_props, + virJSONValue *cpu_deprecated_props, qemuMonitorCPUModelInfo **model_info) { g_autoptr(qemuMonitorCPUModelInfo) expanded_model = NULL; @@ -5116,6 +5124,12 @@ qemuMonitorJSONParseCPUModelExpansion(const char *cpu_name, if (qemuMonitorJSONParseCPUModel(cpu_name, cpu_props, &expanded_model) < 0) return -1; + if (cpu_deprecated_props && + virJSONValueArraySize(cpu_deprecated_props) && + (!(expanded_model->deprecated_props = virJSONValueArrayToStringList(cpu_deprecated_props)))) { + return -1; + } + *model_info = g_steal_pointer(&expanded_model); return 0; } @@ -5180,6 +5194,7 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitor *mon, g_autoptr(virJSONValue) fullData = NULL; virJSONValue *cpu_model; virJSONValue *cpu_props = NULL; + virJSONValue *cpu_deprecated_props = NULL; const char *cpu_name = ""; int rc; @@ -5193,6 +5208,7 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitor *mon, if (qemuMonitorJSONParseCPUModelExpansionData(data, fail_no_props, &cpu_model, &cpu_props, + &cpu_deprecated_props, &cpu_name) < 0) return -1; @@ -5211,11 +5227,13 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitor *mon, if (qemuMonitorJSONParseCPUModelExpansionData(fullData, fail_no_props, &cpu_model, &cpu_props, + &cpu_deprecated_props, &cpu_name) < 0) return -1; } return qemuMonitorJSONParseCPUModelExpansion(cpu_name, cpu_props, + cpu_deprecated_props, model_info); } diff --git a/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml b/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml index 50e9a60a1f..5e8db88e52 100644 --- a/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml +++ b/tests/qemucapabilitiesdata/caps_9.1.0_s390x.xml @@ -193,6 +193,12 @@ <property name='te' type='boolean' value='true'/> <property name='cmm' type='boolean' value='true'/> <property name='vxpdeh2' type='boolean' value='true'/> + <deprecatedFeatures> + <property name='bpb'/> + <property name='te'/> + <property name='cte'/> + <property name='csske'/> + </deprecatedFeatures> </hostCPU> <cpu type='kvm' name='z13' typename='z13-s390x-cpu' usable='yes'/> <cpu type='kvm' name='z990.3' typename='z990.3-s390x-cpu' usable='yes'/> diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml b/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml index 68a6778a25..0fa73e9918 100644 --- a/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml +++ b/tests/qemucapabilitiesdata/caps_9.2.0_s390x.xml @@ -195,6 +195,12 @@ <property name='te' type='boolean' value='true'/> <property name='cmm' type='boolean' value='true'/> <property name='vxpdeh2' type='boolean' value='true'/> + <deprecatedFeatures> + <property name='bpb'/> + <property name='te'/> + <property name='cte'/> + <property name='csske'/> + </deprecatedFeatures> </hostCPU> <cpu type='kvm' name='z13' typename='z13-s390x-cpu' usable='yes'/> <cpu type='kvm' name='z990.3' typename='z990.3-s390x-cpu' usable='yes'/> -- 2.45.1