From: Sandesh Patel <[email protected]>

Persist the list of ARM CPU properties and their host-supported values
that was probed from QEMU into the on-disk QEMU capabilities cache, so
that subsequent libvirtd starts do not have to re-issue the QMP query.

Signed-off-by: Sandesh Patel <[email protected]>
---
 src/qemu/qemu_capabilities.c | 117 ++++++++++++++++++++++++++++++++++-
 1 file changed, 116 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index d79941f6bd..d314956f46 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4531,6 +4531,79 @@ virQEMUCapsLoadMachines(virQEMUCapsAccel *caps,
 }
 
 
+static int
+virQEMUCapsLoadCPUProps(virQEMUCaps *qemuCaps,
+                        xmlXPathContextPtr ctxt)
+{
+    g_autoptr(qemuMonitorCPUPropsInfoList) cpuProps = NULL;
+    g_autofree xmlNodePtr *nodes = NULL;
+    int nprops;
+    size_t i;
+
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
+
+    if ((nprops = virXPathNodeSet("/qemuCaps/cpuPropertyInfo/property",
+                                  ctxt, &nodes)) < 0)
+        return -1;
+
+    if (nprops == 0)
+        return 0;
+
+    cpuProps = g_new0(qemuMonitorCPUPropsInfoList, 1);
+    cpuProps->nprops = nprops;
+    cpuProps->props = g_new0(qemuMonitorCPUPropsInfo, nprops);
+
+    for (i = 0; i < (size_t) nprops; i++) {
+        qemuMonitorCPUPropsInfo *prop = cpuProps->props + i;
+        g_autofree char *type_str = NULL;
+        g_autofree xmlNodePtr *svsNodes = NULL;
+        int nsvs;
+        size_t j;
+
+        if (!(prop->name = virXMLPropString(nodes[i], "name"))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("missing property name in QEMU capabilities 
cache"));
+            return -1;
+        }
+
+        if (!(type_str = virXMLPropString(nodes[i], "type"))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("missing property type in QEMU capabilities cache 
for property '%1$s'"),
+                           prop->name);
+            return -1;
+        }
+        if ((prop->type = qemuMonitorCPUPropertyTypeFromString(type_str)) < 0) 
{
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("unknown property type '%1$s' in QEMU 
capabilities cache for property '%2$s'"),
+                           type_str, prop->name);
+            return -1;
+        }
+
+        prop->composite = virXMLPropString(nodes[i], "composite");
+
+        ctxt->node = nodes[i];
+        if ((nsvs = virXPathNodeSet("./supportedValue", ctxt, &svsNodes)) < 0)
+            return -1;
+
+        if (nsvs == 0)
+            continue;
+
+        prop->supportedValues = g_new0(char *, nsvs + 1);
+        for (j = 0; j < (size_t) nsvs; j++) {
+            if (!(prop->supportedValues[j] = virXMLPropString(svsNodes[j], 
"value"))) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("missing 'value' attribute in QEMU 
capabilities cache for property '%1$s'"),
+                               prop->name);
+                return -1;
+            }
+        }
+    }
+
+    qemuCaps->kvm.cpuProps = g_steal_pointer(&cpuProps);
+    return 0;
+}
+
+
 static int
 virQEMUCapsLoadAccel(virQEMUCaps *qemuCaps,
                      xmlXPathContextPtr ctxt,
@@ -5089,6 +5162,9 @@ virQEMUCapsLoadCache(virArch hostArch,
         virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, 
VIR_DOMAIN_VIRT_HYPERV);
     virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU);
 
+    if (virQEMUCapsLoadCPUProps(qemuCaps, ctxt) < 0)
+        return -1;
+
     if (virXPathBoolean("boolean(./kvmSupportsNesting)", ctxt) > 0)
         qemuCaps->kvmSupportsNesting = true;
 
@@ -5182,6 +5258,45 @@ virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsAccel *caps,
 }
 
 
+static void
+virQEMUCapsFormatCPUProps(virQEMUCapsAccel *caps, virBuffer *buf)
+{
+    qemuMonitorCPUPropsInfoList *cpuProps = caps->cpuProps;
+    size_t i;
+
+    if (!cpuProps)
+        return;
+
+    virBufferAddLit(buf, "<cpuPropertyInfo>\n");
+    virBufferAdjustIndent(buf, 2);
+
+    for (i = 0; i < cpuProps->nprops; i++) {
+        qemuMonitorCPUPropsInfo *prop = cpuProps->props + i;
+
+        virBufferEscapeString(buf, "<property name='%s'", prop->name);
+        virBufferAsprintf(buf, " type='%s'",
+                          qemuMonitorCPUPropertyTypeToString(prop->type));
+        virBufferEscapeString(buf, " composite='%s'", prop->composite);
+        virBufferAddLit(buf, ">\n");
+
+        virBufferAdjustIndent(buf, 2);
+        if (prop->supportedValues) {
+            size_t j;
+
+            for (j = 0; prop->supportedValues[j]; j++) {
+                virBufferEscapeString(buf, "<supportedValue value='%s'/>\n",
+                                      prop->supportedValues[j]);
+            }
+        }
+        virBufferAdjustIndent(buf, -2);
+        virBufferAddLit(buf, "</property>\n");
+    }
+
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "</cpuPropertyInfo>\n");
+}
+
+
 static void
 virQEMUCapsFormatCPUModels(virArch arch,
                            virQEMUCapsAccel *caps,
@@ -5275,7 +5390,7 @@ virQEMUCapsFormatAccel(virQEMUCaps *qemuCaps,
     virQEMUCapsFormatHostCPUModelInfo(caps, buf, typeStr);
     virQEMUCapsFormatCPUModels(qemuCaps->arch, caps, buf, typeStr);
     virQEMUCapsFormatMachines(caps, buf, typeStr);
-
+    virQEMUCapsFormatCPUProps(caps, buf);
 }
 
 
-- 
2.43.7

Reply via email to