[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

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



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 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;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]