[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH] virsh: Allow using complete <capabilities> elements with cpu-baseline



This patch cleans the cpu baseline function using new libvirt helper
functions and fixes XPath expression that selects <cpu> elements from
the source file, that can contain concatenated <capabilities> XMLs,
domain XMLs and bare <cpu> elements. The fixed XPath expression ensures
not to select NUMA <cpu id=... elements.

https://bugzilla.redhat.com/show_bug.cgi?id=731645
---
 tools/virsh.c |   88 ++++++++++++++++++++++++--------------------------------
 1 files changed, 38 insertions(+), 50 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index 3c6e65a..7ea5e1b 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -11908,18 +11908,18 @@ static bool
 cmdCPUBaseline(vshControl *ctl, const vshCmd *cmd)
 {
     const char *from = NULL;
-    bool ret = true;
+    bool ret = false;
     char *buffer;
     char *result = NULL;
     const char **list = NULL;
-    unsigned int count = 0;
-    xmlDocPtr doc = NULL;
-    xmlNodePtr node_list;
+    int count = 0;
+
+    xmlDocPtr xml = NULL;
+    xmlNodePtr *node_list = NULL;
     xmlXPathContextPtr ctxt = NULL;
-    xmlSaveCtxtPtr sctxt = NULL;
-    xmlBufferPtr buf = NULL;
-    xmlXPathObjectPtr obj = NULL;
-    int res, i;
+    xmlBufferPtr xml_buf = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    int i;

     if (!vshConnectionUsability(ctl, ctl->conn))
         return false;
@@ -11930,69 +11930,57 @@ cmdCPUBaseline(vshControl *ctl, const vshCmd *cmd)
     if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0)
         return false;

-    doc = xmlNewDoc(NULL);
-    if (doc == NULL)
+    /* add an separate container around the xml */
+    virBufferStrcat(&buf, "<container>", buffer, "</container>", NULL);
+    if (virBufferError(&buf))
         goto no_memory;

-    res = xmlParseBalancedChunkMemory(doc, NULL, NULL, 0,
-                                      (const xmlChar *)buffer, &node_list);
-    if (res != 0) {
-        vshError(ctl, _("Failed to parse XML fragment %s"), from);
-        ret = false;
+    VIR_FREE(buffer);
+    buffer = virBufferContentAndReset(&buf);
+
+
+    if (!(xml = virXMLParseStringCtxt(buffer, from, &ctxt)))
+        goto cleanup;
+
+    if ((count = virXPathNodeSet("//cpu[not(ancestor::cpus)]",
+                                 ctxt, &node_list)) == -1)
+        goto cleanup;
+
+    if (count == 0) {
+        vshError(ctl, _("No host CPU specified in '%s'"), from);
         goto cleanup;
     }

-    xmlAddChildList((xmlNodePtr) doc, node_list);
+    list = vshCalloc(ctl, count, sizeof(const char *));

-    ctxt = xmlXPathNewContext(doc);
-    if (!ctxt)
+    if (!(xml_buf = xmlBufferCreate()))
         goto no_memory;

-    obj = xmlXPathEval(BAD_CAST "//cpu[not(ancestor::cpu)]", ctxt);
-    if ((obj == NULL) || (obj->nodesetval == NULL) ||
-        (obj->nodesetval->nodeTab == NULL))
-        goto cleanup;
+    for (i = 0; i < count; i++) {
+        xmlBufferEmpty(xml_buf);

-    for (i = 0;i < obj->nodesetval->nodeNr;i++) {
-        buf = xmlBufferCreate();
-        if (buf == NULL)
-            goto no_memory;
-        sctxt = xmlSaveToBuffer(buf, NULL, 0);
-        if (sctxt == NULL) {
-            xmlBufferFree(buf);
-            goto no_memory;
+        if (xmlNodeDump(xml_buf, xml,  node_list[i], 0, 0) < 0) {
+            vshError(ctl, _("Failed to extract <cpu> element"));
+            goto cleanup;
         }

-        xmlSaveTree(sctxt, obj->nodesetval->nodeTab[i]);
-        xmlSaveClose(sctxt);
-
-        list = vshRealloc(ctl, list, sizeof(char *) * (count + 1));
-        list[count++] = (char *) buf->content;
-        buf->content = NULL;
-        xmlBufferFree(buf);
-        buf = NULL;
-    }
-
-    if (count == 0) {
-        vshError(ctl, _("No host CPU specified in '%s'"), from);
-        ret = false;
-        goto cleanup;
+        list[i] = vshStrdup(ctl, (const char *)xmlBufferContent(xml_buf));
     }

     result = virConnectBaselineCPU(ctl->conn, list, count, 0);

-    if (result)
+    if (result) {
         vshPrint(ctl, "%s", result);
-    else
-        ret = false;
+        ret = true;
+    }

 cleanup:
-    xmlXPathFreeObject(obj);
     xmlXPathFreeContext(ctxt);
-    xmlFreeDoc(doc);
+    xmlFreeDoc(xml);
+    xmlBufferFree(xml_buf);
     VIR_FREE(result);
     if ((list != NULL) && (count > 0)) {
-        for (i = 0;i < count;i++)
+        for (i = 0; i < count; i++)
             VIR_FREE(list[i]);
     }
     VIR_FREE(list);
-- 
1.7.3.4


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]