[PATCH v2 26/27] virsh: Introduce --virtio to setmem

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

 



Provide an user friendly way of modifying 'requested-size' of a
virtio-mem device. New --node and --alias arguments are
introduced but they are needed only if it is not clear which
virtio-mem does user mean.

Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx>
---
 docs/manpages/virsh.rst |   6 ++
 tools/virsh-domain.c    | 126 ++++++++++++++++++++++++++++++++++++----
 2 files changed, 122 insertions(+), 10 deletions(-)

diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index 9ef6b68422..c3c8c27a18 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -4098,6 +4098,7 @@ setmem
 ::
 
    setmem domain size [[--config] [--live] | [--current]]
+      [--virtio [--node NODE] | [--alias ALIAS]]
 
 Change the memory allocation for a guest domain.
 If *--live* is specified, perform a memory balloon of a running guest.
@@ -4107,6 +4108,11 @@ If *--current* is specified, it is equivalent to either *--live* or
 Both *--live* and *--config* flags may be given, but *--current* is
 exclusive. If no flag is specified, behavior is different depending
 on hypervisor.
+If *--virtio* is specified then instead of changing the memory allocation for
+whole domain the individual memory device with virtio model is changed. If
+there is more than one such memory device then *--node* or *--alias* must be
+used to specify the device uniquely. *NODE* refers to the guest NUMA node to
+which the memory device is attached to and *ALIAS* is the device alias.
 
 *size* is a scaled integer (see ``NOTES`` above); it defaults to kibibytes
 (blocks of 1024 bytes) unless you provide a suffix (and the older option
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index eeeeaa8639..7d8546d806 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -8992,12 +8992,101 @@ static const vshCmdOptDef opts_setmem[] = {
      .flags = VSH_OFLAG_REQ,
      .help = N_("new memory size, as scaled integer (default KiB)")
     },
+    {.name = "virtio",
+     .type = VSH_OT_BOOL,
+     .help = N_("modify virtio memory instead of top level domain memory")
+    },
+    {.name = "node",
+     .type = VSH_OT_INT,
+     .help = N_("guest numa node"),
+    },
+    {.name = "alias",
+     .type = VSH_OT_STRING,
+     .help = N_("memory device alias"),
+    },
     VIRSH_COMMON_OPT_DOMAIN_CONFIG,
     VIRSH_COMMON_OPT_DOMAIN_LIVE,
     VIRSH_COMMON_OPT_DOMAIN_CURRENT,
     {.name = NULL}
 };
 
+
+static int
+virshDomainSetmemVirtio(vshControl *ctl,
+                        virDomainPtr dom,
+                        unsigned long kibibytes,
+                        int numaNode,
+                        const char *alias,
+                        unsigned int flags)
+{
+    g_autoptr(xmlDoc) doc = NULL;
+    g_autoptr(xmlXPathContext) ctxt = NULL;
+    g_autofree char *xpath = NULL;
+    int nmems;
+    g_autofree xmlNodePtr *mems = NULL;
+    xmlNodePtr requestedSizeNode = NULL;
+    g_autofree char *kibibytesStr = NULL;
+    g_autoptr(xmlBuffer) xmlbuf = NULL;
+    unsigned int domainXMLFlags = 0;
+    const char *updatedMemoryXML = NULL;
+
+    if (flags & VIR_DOMAIN_AFFECT_CONFIG)
+        domainXMLFlags |= VIR_DOMAIN_XML_INACTIVE;
+
+    if (virshDomainGetXMLFromDom(ctl, dom, domainXMLFlags, &doc, &ctxt) < 0)
+        return -1;
+
+    if (alias) {
+        xpath = g_strdup_printf("/domain/devices/memory[./alias/@name='%s']", alias);
+    } else if (numaNode >= 0) {
+        xpath = g_strdup_printf("/domain/devices/memory[./target/node/text()=%d]", numaNode);
+    } else {
+        xpath = g_strdup("/domain/devices/memory[@model='virtio' and not(./source/pmem)]");
+    }
+
+    nmems = virXPathNodeSet(xpath, ctxt, &mems);
+    if (nmems < 0) {
+        vshSaveLibvirtError();
+        return -1;
+    } else if (nmems == 0) {
+        vshError(ctl, _("no virtio-mem device found"));
+        return -1;
+    } else if (nmems > 1) {
+        vshError(ctl, _("multiple virtio-mem devices found"));
+        return -1;
+    }
+
+    ctxt->node = mems[0];
+
+    requestedSizeNode = virXPathNode("./target/requested", ctxt);
+
+    if (!requestedSizeNode) {
+        vshError(ctl, _("virtio-mem device is missing <requested/>"));
+        return -1;
+    }
+
+    kibibytesStr = g_strdup_printf("%lu", kibibytes);
+    xmlNodeSetContent(requestedSizeNode, BAD_CAST kibibytesStr);
+
+    if (!(xmlbuf = xmlBufferCreate())) {
+        vshError(ctl, _("unable to allocate XML buffer"));
+        return -1;
+    }
+
+    if (xmlNodeDump(xmlbuf, doc, mems[0], 0, 1) < 0) {
+        vshError(ctl, _("unable to format new <memory/> node"));
+        return -1;
+    }
+
+    updatedMemoryXML = (const char *)xmlBufferContent(xmlbuf);
+
+    if (virDomainUpdateDeviceFlags(dom, updatedMemoryXML, flags) < 0)
+        return -1;
+
+    return 0;
+}
+
+
 static bool
 cmdSetmem(vshControl *ctl, const vshCmd *cmd)
 {
@@ -9005,7 +9094,7 @@ cmdSetmem(vshControl *ctl, const vshCmd *cmd)
     unsigned long long bytes = 0;
     unsigned long long max;
     unsigned long kibibytes = 0;
-    bool ret = true;
+    bool ret = false;
     bool config = vshCommandOptBool(cmd, "config");
     bool live = vshCommandOptBool(cmd, "live");
     bool current = vshCommandOptBool(cmd, "current");
@@ -9013,6 +9102,7 @@ cmdSetmem(vshControl *ctl, const vshCmd *cmd)
 
     VSH_EXCLUSIVE_OPTIONS_VAR(current, live);
     VSH_EXCLUSIVE_OPTIONS_VAR(current, config);
+    VSH_EXCLUSIVE_OPTIONS("node", "alias");
 
     if (config)
         flags |= VIR_DOMAIN_AFFECT_CONFIG;
@@ -9028,20 +9118,36 @@ cmdSetmem(vshControl *ctl, const vshCmd *cmd)
         max = 1024ull * ULONG_MAX;
     else
         max = ULONG_MAX;
-    if (vshCommandOptScaledInt(ctl, cmd, "size", &bytes, 1024, max) < 0) {
-        virshDomainFree(dom);
-        return false;
-    }
+    if (vshCommandOptScaledInt(ctl, cmd, "size", &bytes, 1024, max) < 0)
+        goto cleanup;
+
     kibibytes = VIR_DIV_UP(bytes, 1024);
 
-    if (flags == 0) {
-        if (virDomainSetMemory(dom, kibibytes) != 0)
-            ret = false;
+    if (vshCommandOptBool(cmd, "virtio")) {
+        int numaNode = -1;
+        const char *alias = NULL;
+
+        if (vshCommandOptInt(ctl, cmd, "node", &numaNode) < 0)
+            goto cleanup;
+
+        if (vshCommandOptStringReq(ctl, cmd, "alias", &alias) < 0)
+            goto cleanup;
+
+        if (virshDomainSetmemVirtio(ctl, dom, kibibytes,
+                                    numaNode, alias, flags) < 0)
+            goto cleanup;
     } else {
-        if (virDomainSetMemoryFlags(dom, kibibytes, flags) < 0)
-            ret = false;
+        if (flags == 0) {
+            if (virDomainSetMemory(dom, kibibytes) != 0)
+                goto cleanup;
+        } else {
+            if (virDomainSetMemoryFlags(dom, kibibytes, flags) < 0)
+                goto cleanup;
+        }
     }
 
+    ret = true;
+ cleanup:
     virshDomainFree(dom);
     return ret;
 }
-- 
2.26.2




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux