]> xenbits.xensource.com Git - libvirt.git/commitdiff
virsh: Allow using complete <capabilities> elements with cpu-baseline
authorPeter Krempa <pkrempa@redhat.com>
Thu, 15 Sep 2011 11:51:01 +0000 (13:51 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Wed, 28 Sep 2011 07:17:56 +0000 (09:17 +0200)
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.

This patch also removes vshRealloc function, that remained unused after
cleaning up cpu-baseline.

https://bugzilla.redhat.com/show_bug.cgi?id=731645

tools/virsh.c

index c72c1a560f5b7c942722e492000d1d1f5a95ce25..13be03b17df6dfd3ead4cc4c9f3cd4ae3407bd07 100644 (file)
@@ -384,9 +384,6 @@ static void *_vshMalloc(vshControl *ctl, size_t sz, const char *filename, int li
 static void *_vshCalloc(vshControl *ctl, size_t nmemb, size_t sz, const char *filename, int line);
 #define vshCalloc(_ctl, _nmemb, _sz)    _vshCalloc(_ctl, _nmemb, _sz, __FILE__, __LINE__)
 
-static void *_vshRealloc(vshControl *ctl, void *ptr, size_t sz, const char *filename, int line);
-#define vshRealloc(_ctl, _ptr, _sz)    _vshRealloc(_ctl, _ptr, _sz, __FILE__, __LINE__)
-
 static char *_vshStrdup(vshControl *ctl, const char *s, const char *filename, int line);
 #define vshStrdup(_ctl, _s)    _vshStrdup(_ctl, _s, __FILE__, __LINE__)
 
@@ -414,19 +411,6 @@ _vshCalloc(vshControl *ctl, size_t nmemb, size_t size, const char *filename, int
     exit(EXIT_FAILURE);
 }
 
-static void *
-_vshRealloc(vshControl *ctl, void *ptr, size_t size, const char *filename, int line)
-{
-    void *x;
-
-    if ((x = realloc(ptr, size)))
-        return x;
-    VIR_FREE(ptr);
-    vshError(ctl, _("%s: %d: failed to allocate %d bytes"),
-             filename, line, (int) size);
-    exit(EXIT_FAILURE);
-}
-
 static char *
 _vshStrdup(vshControl *ctl, const char *s, const char *filename, int line)
 {
@@ -12003,18 +11987,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;
@@ -12025,69 +12009,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);