[libvirt] [PATCHv1 2/7] qemu_capabilities: CPUModelInfo: XML/QMP format conversion

Chris Venteicher cventeic at redhat.com
Sat May 5 17:48:44 UTC 2018


Functions converting directly between virsh XML and QMEU QMP forms of
CPUModelInfo.
---
 src/qemu/qemu_capabilities.c | 159 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 159 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 0265d83028..afce3eb2b7 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3341,6 +3341,165 @@ virQEMUCapsLoadCache(virArch hostArch,
 }
 
 
+/* <cpu>
+ *   <arch>s390x</arch>
+ *   <model>z13-base</model>
+ *   <feature name='xxx'/>
+ *   ...
+ *   <feature name='yyy'/>
+ * </cpu>
+ *
+ * returns  0,  (*model), Success
+ * returns  0, !(*model), Content not found
+ * returns -1, !(*model), Failure
+ */
+static int
+virQEMUCapsCPUModelInfoFromXML(xmlXPathContextPtr ctxt,
+                               const char *xpath,
+                               qemuMonitorCPUModelInfoPtr *model)
+{
+    size_t i;
+    int ret = -1;
+    qemuMonitorCPUModelInfoPtr cpuModel = NULL;
+    xmlNodePtr *nodes = NULL;
+    xmlNodePtr oldnode = ctxt->node;
+
+    VIR_DEBUG("xpath =%s", NULLSTR(xpath));
+
+    *model = NULL;
+
+    /* optional xpath query for cpu node with nonerror exit on miss */
+    if (xpath && !(ctxt->node = virXPathNode(xpath, ctxt))) {
+        ret = 0;
+        goto cleanup;
+    }
+
+    if (!virXMLNodeNameEqual(ctxt->node, "cpu")) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("XML does not contain expected 'cpu' element"));
+        goto cleanup;
+    }
+
+    if (VIR_ALLOC(cpuModel) < 0)
+        goto cleanup;
+
+    if (!(cpuModel->name = virXPathString("string(./model[1])", ctxt))) {
+        virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing CPU model name"));
+        goto cleanup;
+    }
+
+    cpuModel->nprops = virXPathNodeSet("./feature", ctxt, &nodes);
+
+    if (VIR_ALLOC_N(cpuModel->props, cpuModel->nprops) < 0)
+        goto cleanup;
+
+    for (i = 0; i < cpuModel->nprops; i++) {
+        qemuMonitorCPUPropertyPtr prop = &(cpuModel->props[i]);
+
+        prop->type = QEMU_MONITOR_CPU_PROPERTY_BOOLEAN;
+        prop->value.boolean = true;
+        prop->migratable = VIR_TRISTATE_BOOL_ABSENT;
+
+        if (!(prop->name = virXMLPropString(nodes[i], "name"))) {
+            virReportError(VIR_ERR_XML_ERROR, "%s", _("Invalid CPU feature name"));
+            goto cleanup;
+        }
+    }
+
+    *model = qemuMonitorCPUModelInfoCopy(cpuModel);
+
+    ret = 0;
+
+    VIR_DEBUG("model->name = %s", NULLSTR((*model)->name));
+
+ cleanup:
+    ctxt->node = oldnode;
+    VIR_FREE(nodes);
+    qemuMonitorCPUModelInfoFree(cpuModel);
+    return ret;
+}
+
+
+/*
+ * returns  0,  (*model), Success
+ * returns  0, !(*model), Content not found
+ * returns -1, !(*model), Failure
+ */
+static int
+virQEMUCapsLoadCPUModelInfoFromXMLString(const char *xml,
+                                         const char *xpath,
+                                         qemuMonitorCPUModelInfoPtr *model)
+{
+    int ret = -1;
+
+    xmlDocPtr doc = NULL;
+    xmlXPathContextPtr ctxt = NULL;
+
+    *model = NULL;
+
+    VIR_DEBUG("input = %s", NULLSTR(xml));
+
+    if (!(doc = virXMLParseStringCtxt(xml, _("(CPU_definition)"), &ctxt))) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s", _("missing CPU definition"));
+        goto cleanup;
+    }
+
+    if (virQEMUCapsCPUModelInfoFromXML(ctxt, xpath, model) < 0) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("XML does not contain expected 'cpu' element"));
+        goto cleanup;
+    }
+
+    ret = 0;
+
+ cleanup:
+    xmlXPathFreeContext(ctxt);
+    xmlFreeDoc(doc);
+
+    return ret;
+}
+
+
+/* <cpu match='exact'>
+ *  <model>z13-base</model>
+ *  <feature policy='require' name='xxx'/>
+ *  <feature policy='require' name='yyy'/>
+ * </cpu>
+ */
+static void
+virQEMUCapsCPUModelInfoToXML(qemuMonitorCPUModelInfoPtr model, virBufferPtr buf)
+{
+    size_t i;
+
+    if (!model)
+        return;
+
+    virBufferAddLit(buf, "<cpu match='exact'>\n");
+
+    virBufferAdjustIndent(buf, 2);
+
+    virBufferAsprintf(buf, "<model>%s</model>\n", model->name);
+
+    for (i = 0; i < model->nprops; i++) {
+        qemuMonitorCPUPropertyPtr prop = &(model->props[i]);
+
+        virBufferAsprintf(buf, "<feature policy='require' name='%s'/>\n",
+                          prop->name);
+    }
+
+    virBufferAdjustIndent(buf, -2);
+
+    virBufferAddLit(buf, "</cpu>\n");
+}
+
+
+/*
+ * <hostCPU type='%s' model='%s' migratability='%s'>
+ *   <property name='%s' type='%s' value='%s'/>
+ *   ...
+ *   <property name='%s' type='%s' value='%s'/>
+ * </hostCPU>
+ */
 static void
 virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsPtr qemuCaps,
                                   virBufferPtr buf,
-- 
2.14.1




More information about the libvir-list mailing list