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