[libvirt] [PATCH v2 9/9] reworked cpu-baseline command for virsh

Daniel Veillard veillard at redhat.com
Fri Feb 12 16:39:46 UTC 2010


 I'm not saying it's any easier to read, but from an XML standpoint
it's far cleaner. It still accepts random concatenation of files with
<cpu> being defined, note that the XPath query will only pick top
<cpu> in case there is some recursion (//cpu[not(ancestor::cpu)] does
the trick :)

 It works as previously:

paphio:~/libvirt/tools -> ./virsh cpu-baseline  baseline
<cpu match='exact'>
  <model>qemu32</model>
  <feature policy='require' name='monitor'/>
  <feature policy='require' name='pse36'/>
</cpu>

paphio:~/libvirt/tools ->

  with baseline containing the weird concatenation shown in 0/9 :-)

Daniel

diff --git a/tools/virsh.c b/tools/virsh.c
index 7db48d9..95f5801 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -34,6 +34,7 @@
 #include <libxml/parser.h>
 #include <libxml/tree.h>
 #include <libxml/xpath.h>
+#include <libxml/xmlsave.h>
 
 #ifdef HAVE_READLINE_READLINE_H
 #include <readline/readline.h>
@@ -7025,6 +7026,121 @@ cmdCPUCompare(vshControl *ctl, const vshCmd *cmd)
     return ret;
 }
 
+/*
+ * "cpu-baseline" command
+ */
+static const vshCmdInfo info_cpu_baseline[] = {
+    {"help", gettext_noop("compute baseline CPU")},
+    {"desc", gettext_noop("Compute baseline CPU for a set of given CPUs.")},
+    {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_cpu_baseline[] = {
+    {"file", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("file containing XML CPU descriptions")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdCPUBaseline(vshControl *ctl, const vshCmd *cmd)
+{
+    char *from;
+    int found;
+    int ret = TRUE;
+    char *buffer;
+    char *p;
+    char *result = NULL;
+    const char **list = NULL;
+    unsigned int count = 0;
+    xmlDocPtr doc = NULL;
+    xmlNodePtr node_list, cur;
+    xmlXPathContextPtr ctxt = NULL;
+    xmlSaveCtxtPtr sctxt = NULL;
+    xmlBufferPtr buf = NULL;
+    xmlXPathObjectPtr obj = NULL;
+    int res, i;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    from = vshCommandOptString(cmd, "file", &found);
+    if (!found)
+        return FALSE;
+
+    if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0)
+        return FALSE;
+
+    doc = xmlNewDoc(NULL);
+    if (doc == NULL)
+        goto no_memory;
+
+    res = xmlParseBalancedChunkMemory(doc, NULL, NULL, 0, buffer, &node_list);
+    if (res != 0) {
+        vshError(ctl, _("Failed to parse XML fragment %s"), from);
+        ret = FALSE;
+        goto cleanup;
+    }
+
+    xmlAddChildList((xmlNodePtr) doc, node_list);
+
+    ctxt = xmlXPathNewContext(doc);
+    if (!ctxt)
+        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 < obj->nodesetval->nodeNr;i++) {
+        buf = xmlBufferCreate();
+        if (buf == NULL)
+            goto no_memory;
+        sctxt = xmlSaveToBuffer(buf, NULL, 0);
+        if (sctxt == NULL)
+            goto no_memory;
+
+        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;
+    }
+
+    result = virConnectBaselineCPU(ctl->conn, list, count, 0);
+
+    if (result)
+        vshPrint(ctl, "%s", result);
+    else
+        ret = FALSE;
+
+cleanup:
+    xmlXPathFreeObject(obj);
+    xmlXPathFreeContext(ctxt);
+    xmlFreeDoc(doc);
+    VIR_FREE(result);
+    if ((list != NULL) && (count > 0)) {
+        for (i = 0;i < count;i++)
+            VIR_FREE(list[i]);
+    }
+    VIR_FREE(list);
+    VIR_FREE(buffer);
+
+    return ret;
+
+no_memory:
+    vshError(ctl, "%s", _("Out of memory"));
+    ret = FALSE;
+}
+
 /* Common code for the edit / net-edit / pool-edit functions which follow. */
 static char *
 editWriteToTempFile (vshControl *ctl, const char *doc)
@@ -7396,6 +7512,7 @@ static const vshCmdDef commands[] = {
 #ifndef WIN32
     {"console", cmdConsole, opts_console, info_console},
 #endif
+    {"cpu-baseline", cmdCPUBaseline, opts_cpu_baseline, info_cpu_baseline},
     {"cpu-compare", cmdCPUCompare, opts_cpu_compare, info_cpu_compare},
     {"create", cmdCreate, opts_create, info_create},
     {"start", cmdStart, opts_start, info_start},
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 10f622f..8f6df19 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -213,6 +213,14 @@ crashed.
 Prints the available amount of memory on the machine or within a
 NUMA cell if I<cellno> is provided.
 
+=item B<cpu-baseline> I<FILE>
+
+Compute baseline CPU which will be supported by all host CPUs given in <file>.
+The list of host CPUs is built by extracting all <cpu> elements from the
+<file>. Thus, the <file> can contain either a set of <cpu> elements separated
+by new lines or even a set of complete <capabilities> elements printed by
+B<capabilities> command.
+
 =item B<cpu-compare> I<FILE>
 
 Compare CPU definition from XML <file> with host CPU. The XML <file> may

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list