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(a)huawei.com>
Signed-off-by: Li Bin <binlibin.li(a)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