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