[libvirt] [PATCH 7/8] qemu: memory: logically hotplug memory with guest agent

Zhang Bo oscar.zhangbo at huawei.com
Tue Jun 9 09:33:31 UTC 2015


hotplug memory with guest agent. It
1 get memory block list, each member has 'phy-index', 'online' and 'can-offline' parameters
2 get memory block size, normally 128MB or 256MB for most OSes
3 convert the target memory size to memory block number, and see if there's enough memory
  blocks to be set online/offline.
4 update the memory block list info, and let guest agent to set memory blocks online/offline.

note: because we hotplug memory logically by online/offline MEMORY BLOCKS, and each memory block has
a size much bigger than KiB, there's a deviation with the range of (0, block_size).

Signed-off-by: Zhang Bo <oscar.zhangbo at huawei.com>
Signed-off-by: Li Bin <binlibin.li at huawei.com>
---
 src/qemu/qemu_driver.c | 42 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 580cd60..2a20bef 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2307,6 +2307,10 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
     virDomainDefPtr persistentDef;
     int ret = -1, r;
     virQEMUDriverConfigPtr cfg = NULL;
+    qemuAgentMemblockInfoPtr memblocks = NULL;
+    int nblocks = 0;
+    qemuAgentMemblockGeneralInfoPtr meminfo = NULL;
+    unsigned long long newmem_MB = newmem >> 10;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG |
@@ -2368,6 +2372,41 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
         /* resize the current memory */
         unsigned long oldmax = 0;
 
+        priv = vm->privateData;
+
+        if (flags & VIR_DOMAIN_MEM_GUEST) {
+            if (!qemuDomainAgentAvailable(vm, true))
+                goto endjob;
+
+            if (VIR_ALLOC(meminfo)) {
+                virReportOOMError();
+                goto endjob;
+            }
+
+            qemuDomainObjEnterAgent(vm);
+            nblocks = qemuAgentGetMemblocks(priv->agent, &memblocks);
+            qemuDomainObjExitAgent(vm);
+
+            if (nblocks < 0)
+                goto endjob;
+
+            qemuDomainObjEnterAgent(vm);
+            ret = qemuAgentGetMemblockGeneralInfo(priv->agent, meminfo);
+            qemuDomainObjExitAgent(vm);
+
+            if (ret < 0)
+                goto endjob;
+
+            if (qemuAgentUpdateMemblocks(newmem_MB, memblocks, nblocks, meminfo->blockSize))
+                goto endjob;
+
+            qemuDomainObjEnterAgent(vm);
+            ret = qemuAgentSetMemblocks(priv->agent, memblocks, nblocks);
+            qemuDomainObjExitAgent(vm);
+
+            goto endjob;
+        }
+
         if (def)
             oldmax = virDomainDefGetMemoryActual(def);
         if (persistentDef) {
@@ -2382,7 +2421,6 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
         }
 
         if (def) {
-            priv = vm->privateData;
             qemuDomainObjEnterMonitor(driver, vm);
             r = qemuMonitorSetBalloon(priv->mon, newmem);
             if (qemuDomainObjExitMonitor(driver, vm) < 0)
@@ -2415,6 +2453,8 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
  cleanup:
     virDomainObjEndAPI(&vm);
     virObjectUnref(cfg);
+    VIR_FREE(meminfo);
+    VIR_FREE(memblocks);
     return ret;
 }
 
-- 
1.7.12.4





More information about the libvir-list mailing list