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.zhan...@huawei.com>
Signed-off-by: Li Bin <binlibin...@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


--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to