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@xxxxxxxxxxxxxx> --- 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; } -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list