[libvirt] [PATCH 1/2] virsh: Add a new command "confcpu"

Ken ICHIKAWA ichikawa.ken at jp.fujitsu.com
Tue Dec 25 08:49:53 UTC 2012


From: Ken ICHIKAWA <ichikawa.ken at jp.fujitsu.com>

This patch adds a new virsh command "confcpu", that allows to show and
modify mode attribute and match attribute of a cpu node of a domain XML.
Modification is supported for only persistent configuration.

Examples of usage:
   change cpu mode to "host-passthrough"
     virsh # confcpu <domain> --mode host-passthrough

   change match attribute to "minimum"
     virsh # confcpu <domain> --match minimum

   reset all cpu configuration under a cpu node of a domain XML
     virsh # confcpu <domain> --reset

   show cpu node attirbutes of a running guest
     virsh # confcpu <domain> --live

Signed-off-by: Ken ICHIKAWA <ichikawa.ken at jp.fujitsu.com>
---
  tools/virsh-domain.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++
  tools/virsh.pod      |  24 +++++++
  2 files changed, 210 insertions(+)

diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index f3da1d5..913a1b4 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -5526,6 +5526,191 @@ failed_stats:
  }
  
  /*
+ * "confcpu" command
+ */
+static const vshCmdInfo info_confcpu[] = {
+    {"help", N_("show or modify domain cpu node attributes")},
+    {"desc", N_("Show or modify cpu node attributes of a domain XML")},
+    {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_confcpu[] = {
+    {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
+    {"mode", VSH_OT_DATA, 0,
+     N_("mode attribute, one of custom, host-model and host-passthrough")},
+    {"match", VSH_OT_DATA, 0,
+     N_("match attribute, one of minimum, exact and strict")},
+    {"reset", VSH_OT_BOOL, 0,
+     N_("remove a cpu node including child nodes and redefine the domain XML")},
+    {"live", VSH_OT_BOOL, 0, N_("affect running state")},
+    {"config", VSH_OT_BOOL, 0, N_("affect persistent configuration")},
+    {"current", VSH_OT_BOOL, 0, N_("affect current state configuration")},
+    {NULL, 0, 0, NULL}
+};
+
+static bool
+cmdConfCPU(vshControl *ctl, const vshCmd *cmd)
+{
+    virDomainPtr dom = NULL;
+    virDomainPtr dom_edited = NULL;
+    const char *newMode = NULL;
+    char *curMode = NULL;
+    const char *newMatch = NULL;
+    char *curMatch = NULL;
+    bool reset = vshCommandOptBool(cmd, "reset");
+    bool config = vshCommandOptBool(cmd, "config");
+    bool live = vshCommandOptBool(cmd, "live");
+    bool current = vshCommandOptBool(cmd, "current");
+    int running = -1;
+    bool modify = false; /* Modification mode */
+    unsigned int flags = 0;
+    bool ret = false;
+    char *doc = NULL;
+    char *doc_edited = NULL;
+    xmlXPathContextPtr ctxt = NULL;
+    xmlDocPtr xml = NULL;
+    xmlNodePtr domNode = NULL;
+    xmlNodePtr cpuNode = NULL;
+
+    if (current + config + live > 1) {
+        vshError(ctl, "%s",
+                 _("--config, --live, and --current are mutually exclusive"));
+        return false;
+    }
+
+    if (vshCommandOptString(cmd, "mode", &newMode) < 0 ||
+        vshCommandOptString(cmd, "match", &newMatch) < 0) {
+        vshError(ctl, "%s", _("missing argument"));
+        return false;
+    }
+
+    modify = reset || newMode || newMatch;
+
+    if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
+        return false;
+
+    if ((running = virDomainIsActive(dom)) < 0) {
+        vshError(ctl, "%s", _("Coud not check domain state."));
+        goto cleanup;
+    }
+
+    if (live && !running) {
+        vshError(ctl, "%s", _("--live affects only a running domain"));
+        goto cleanup;
+    }
+    if (modify) {
+        if (live || (current && running)) {
+            vshError(ctl, "%s", _("Cannot modify a running guest."));
+            goto cleanup;
+        }
+    }
+    /* If modification is needed, get persistent conf regardless of
+       other flags because modification of cpu node is supported
+       for only persistent config. */
+    if (config || (current && !running) || modify)
+        flags = VIR_DOMAIN_XML_INACTIVE;
+
+    /* get domain XML */
+    if (!(doc = virDomainGetXMLDesc(dom, flags))) {
+        vshError(ctl, "%s", _("Could not get domain XML."));
+        goto cleanup;
+    }
+
+    if (!(xml = virXMLParseStringCtxt(doc, _("(domain_definition)"), &ctxt))) {
+        vshError(ctl, "%s", _("Could not parse domain XML."));
+        goto cleanup;
+    }
+
+    /* Query mode: show cpu node attributes then exit. */
+    if (!modify) {
+        curMode = virXPathString("string(./cpu[1]/@mode)", ctxt);
+        curMatch = virXPathString("string(./cpu[1]/@match)", ctxt);
+        vshPrint(ctl, "mode  : %s\n", curMode? curMode : "");
+        vshPrint(ctl, "match : %s\n", curMatch? curMatch : "");
+
+        ret = true;
+        goto cleanup;
+    }
+
+    /* Modification mode: modify cpu node. */
+
+    if (reset) {
+        /* remove cpu node */
+        if ((cpuNode = virXPathNode("./cpu[1]", ctxt))) {
+            xmlUnlinkNode(cpuNode);
+            xmlFreeNode(cpuNode);
+            cpuNode = NULL;
+        }
+    }
+
+    if (newMode || newMatch) {
+        /* get cpu node */
+        if (!(cpuNode = virXPathNode("./cpu[1]", ctxt))) {
+            /* get domain node to create a new cpu node */
+            if (!(domNode = virXPathNode("/domain[1]", ctxt))) {
+                vshError(ctl, "%s", _("Could not find domain node."));
+                goto cleanup;
+            }
+            /* create a new cpu node */
+            if (!(cpuNode = xmlNewChild(domNode,
+                                        NULL,
+                                        (const xmlChar*)"cpu",
+                                        NULL))) {
+                vshError(ctl, "%s", _("Could not create new cpu node."));
+                goto cleanup;
+            }
+        }
+    }
+
+    if (newMode) {
+        /* modify mode attribute of the cpu node*/
+        if (!xmlSetProp(cpuNode,
+                        (const xmlChar*)"mode",
+                        (const xmlChar*)newMode)) {
+            vshError(ctl, "%s", _("Could not modify mode attribute."));
+            goto cleanup;
+        }
+    }
+
+    if (newMatch) {
+        /* modify match attribute of the cpu node*/
+        if (!xmlSetProp(cpuNode,
+                        (const xmlChar*)"match",
+                        (const xmlChar*)newMatch)) {
+            vshError(ctl, "%s", _("Could not modify match attribute."));
+            goto cleanup;
+        }
+    }
+
+    /* get modified domain XML */
+    xmlDocDumpMemory(xml, (xmlChar**)&doc_edited, NULL);
+    if (!doc_edited) {
+        vshError(ctl, "%s", _("Could not dump edited XML doc."));
+        goto cleanup;
+    }
+
+    /* update domain XML */
+    if (!(dom_edited = virDomainDefineXML(ctl->conn, doc_edited))) {
+        vshError(ctl, "%s", _("Failed to update cpu node."));
+        goto cleanup;
+    }
+    virDomainFree(dom_edited);
+
+    vshPrint(ctl, "%s", _("Configuration redefined successfully.\n"));
+    ret = true;
+
+ cleanup:
+    VIR_FREE(doc_edited);
+    VIR_FREE(curMatch);
+    VIR_FREE(curMode);
+    xmlFreeDoc(xml);
+    xmlXPathFreeContext(ctxt);
+    VIR_FREE(doc);
+    virDomainFree(dom);
+    return ret;
+}
+
+/*
   * "create" command
   */
  static const vshCmdInfo info_create[] = {
@@ -8507,6 +8692,7 @@ const vshCmdDef domManagementCmds[] = {
      {"blockpull", cmdBlockPull, opts_block_pull, info_block_pull, 0},
      {"blockresize", cmdBlockResize, opts_block_resize, info_block_resize, 0},
      {"change-media", cmdChangeMedia, opts_change_media, info_change_media, 0},
+    {"confcpu", cmdConfCPU, opts_confcpu, info_confcpu, 0},
  #ifndef WIN32
      {"console", cmdConsole, opts_console, info_console, 0},
  #endif
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 3687a4d..6374993 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -538,6 +538,30 @@ the server has to ensure exclusive access to console devices. Optionally
  the I<--force> flag may be specified, requesting to disconnect any existing
  sessions, such as in a case of a broken connection.
  
+=item B<confcpu> I<domain> [I<--mode> I<mode>] [I<--match> I<match>] [I<--reset>] [[I<--current>] | [I<--live>] | [I<--config>]]
+
+Get or set cpu node attributes of a domain XML.
+I<mode> is mode attribute of a cpu node, one of "custom", "host-model"
+and "host-passthrough". If I<mode> is specified, mode attribute is modified.
+I<match> is match attribute of a cpu node, one of "minimum", "exact",
+and "strict". If I<match> is specified, match attribute is modified.
+If I<--reset> is specified, a cpu node is removed including the child
+nodes, so that the cpu configuration under the cpu node of the domain XML
+will be default.
+If I<mode> or I<match> is specified with I<--reset>, these attributes
+are added to a new cpu node after I<--reset> behavior.
+
+These modifications don't affect a running guest state but affects a
+persistent configuration.
+
+If neither of I<mode>, I<match> and I<--reset> are specified, attributes
+of a cpu node are displayed instead of being modified.
+
+If I<--live> is specified, affect a running guest.
+If I<--config> is specified, affect the next boot of a persistent guest.
+If I<--current> is specified, affect the current guest state.
+These three flags are mutually exclusive.
+
  =item B<create> I<FILE> [I<--console>] [I<--paused>] [I<--autodestroy>]
  
  Create a domain from an XML <file>. An easy way to create the XML
-- 
1.7.11.7





More information about the libvir-list mailing list