From: Ken ICHIKAWA <ichikawa.ken(a)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(a)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