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@xxxxxxxxxx> Signed-off-by: Li Bin <binlibin.li@xxxxxxxxxx> --- 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@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list