function qemuAgentUpdateMemblocks() checks whether it needs to plug/unplug memory blocks to reach the target memory. it's similar to qemuAgentUpdateCPUInfo(). Signed-off-by: Zhang Bo <oscar.zhangbo@xxxxxxxxxx> Signed-off-by: Li Bin <binlibin.li@xxxxxxxxxx> --- src/qemu/qemu_agent.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_agent.h | 4 +++ 2 files changed, 73 insertions(+) diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c index 3481354..2c3a5ba 100644 --- a/src/qemu/qemu_agent.c +++ b/src/qemu/qemu_agent.c @@ -1775,6 +1775,75 @@ qemuAgentGetMemblockGeneralInfo(qemuAgentPtr mon, return ret; } +int +qemuAgentUpdateMemblocks(unsigned long long memory, + qemuAgentMemblockInfoPtr info, + int nblock, + unsigned long long blocksize) +{ + size_t i; + int nonline = 0; + int nofflinable = 0; + unsigned long long ntarget = 0; + + if (memory % blocksize) { + ntarget = (int)((memory / blocksize) + 1); + }else { + ntarget = (int)(memory / blocksize); + } + + /* count the active and offlinable memory blocks */ + for (i = 0; i < nblock; i++) { + if (info[i].online) + nonline++; + + if (info[i].offlinable && info[i].online) + nofflinable++; + + /* This shouldn't happen, but we can't trust the guest agent */ + if (!info[i].online && !info[i].offlinable) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Invalid data provided by guest agent")); + return -1; + } + } + + /* the guest agent reported less memory than requested */ + if (ntarget > nblock) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("guest agent reports less memory than requested")); + return -1; + } + + /* not enough offlinable memory blocks to support the request */ + if (ntarget < (nonline - nofflinable)) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("Cannot offline enough memory blocks")); + return -1; + } + + for (i = 0; i < nblock; i++) { + if (ntarget < nonline) { + /* unplug */ + if (info[i].offlinable && info[i].online) { + info[i].online = false; + nonline--; + } + } else if (ntarget > nonline) { + /* plug */ + if (!info[i].online) { + info[i].online = true; + nonline++; + } + } else { + /* done */ + break; + } + } + + return 0; + +} int qemuAgentGetTime(qemuAgentPtr mon, diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h index 9a9b859..3ba6deb 100644 --- a/src/qemu/qemu_agent.h +++ b/src/qemu/qemu_agent.h @@ -119,6 +119,10 @@ struct _qemuAgentMemblockGeneralInfo { int qemuAgentGetMemblocks(qemuAgentPtr mon, qemuAgentMemblockInfoPtr *info); int qemuAgentGetMemblockGeneralInfo(qemuAgentPtr mon, qemuAgentMemblockGeneralInfoPtr info); +int qemuAgentUpdateMemblocks(unsigned long long memory, + qemuAgentMemblockInfoPtr info, + int nblock, + unsigned long long blocksize); int qemuAgentGetTime(qemuAgentPtr mon, long long *seconds, -- 1.7.12.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list