[libvirt] [PATCH] RFC: virsh setmem: configure inactive domains' memory size

Taku Izumi izumi.taku at jp.fujitsu.com
Thu Feb 24 10:25:28 UTC 2011


Currently "virsh setmem" is not allowed to use against inactive domains.
By applying this patch, we can change the memory size of inactive domains
by "virsh setmem".


Signed-off-by: Taku Izumi <izumi.taku at jp.fujitsu.com>
---
 tools/virsh.c |   70 +++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 62 insertions(+), 8 deletions(-)

Index: libvirt-git/tools/virsh.c
===================================================================
--- libvirt-git.orig/tools/virsh.c
+++ libvirt-git/tools/virsh.c
@@ -2919,39 +2919,93 @@ cmdSetmem(vshControl *ctl, const vshCmd
     virDomainPtr dom;
     virDomainInfo info;
     unsigned long kilobytes;
-    int ret = TRUE;
+    int ret = FALSE;
+
+    char *xmlStr;
+    virBuffer memBuf = VIR_BUFFER_INITIALIZER;
+    xmlDocPtr xmlDocObj = NULL;
+    xmlXPathContextPtr ctxt = NULL;
+    xmlXPathObjectPtr result = NULL;
+    xmlChar *newXml = NULL;
+    int newXmlSize;

     if (!vshConnectionUsability(ctl, ctl->conn))
-        return FALSE;
+        return ret;

     if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
-        return FALSE;
+        return ret;

     kilobytes = vshCommandOptUL(cmd, "kilobytes", NULL);
     if (kilobytes <= 0) {
         virDomainFree(dom);
         vshError(ctl, _("Invalid value of %lu for memory size"), kilobytes);
-        return FALSE;
+        return ret;
     }

     if (virDomainGetInfo(dom, &info) != 0) {
         virDomainFree(dom);
         vshError(ctl, "%s", _("Unable to verify MaxMemorySize"));
-        return FALSE;
+        return ret;
     }

     if (kilobytes > info.maxMem) {
         virDomainFree(dom);
         vshError(ctl, _("Requested memory size %lu kb is larger than maximum of %lu
kb"),
                  kilobytes, info.maxMem);
-        return FALSE;
+        return ret;
     }

-    if (virDomainSetMemory(dom, kilobytes) != 0) {
-        ret = FALSE;
+    if (virDomainIsActive(dom) == 1) {
+        if (virDomainSetMemory(dom, kilobytes) == 0)
+            ret = TRUE;
+        virDomainFree(dom);
+        return ret;
     }

+    /* domain is inactive */
+
+    xmlStr = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_SECURE |
+                                      VIR_DOMAIN_XML_INACTIVE);
+    if (!xmlStr)
+        goto cleanup;
+
+    xmlDocObj = xmlReadDoc((const xmlChar *)xmlStr, "domain.xml", NULL,
+                           XML_PARSE_NOENT | XML_PARSE_NONET |
+                           XML_PARSE_NOWARNING);
+    if (!xmlDocObj)
+        goto cleanup;
+
+    ctxt = xmlXPathNewContext(xmlDocObj);
+    if (!ctxt)
+        goto cleanup;
+
+    result = xmlXPathEvalExpression((xmlChar *)"/domain/currentMemory", ctxt);
+    if (xmlXPathNodeSetIsEmpty(result->nodesetval) ||
+        result->nodesetval->nodeNr != 1 ||
+        result->nodesetval->nodeTab[0]->type != XML_ELEMENT_NODE) {
+        goto cleanup;
+    }
+
+    virBufferVSprintf(&memBuf, "%lu", kilobytes);
+    xmlNodeSetContent(result->nodesetval->nodeTab[0],
+                      (const xmlChar *)virBufferContentAndReset(&memBuf));
+    xmlDocDumpMemory(xmlDocObj, &newXml, &newXmlSize);
+    if (!newXml)
+        goto cleanup;
+
     virDomainFree(dom);
+    dom = virDomainDefineXML(ctl->conn, (char *)newXml);
+    if (dom)
+        ret = TRUE;
+
+cleanup:
+    xmlFree(newXml);
+    xmlXPathFreeContext(ctxt);
+    xmlFreeDoc(xmlDocObj);
+    VIR_FREE(xmlStr);
+    if (dom)
+        virDomainFree(dom);
+
     return ret;
 }





More information about the libvir-list mailing list