[libvirt] [PATCH 5/8] qemu: agent: implement qemuAgentUpdateMemblocks

Zhang Bo oscar.zhangbo at huawei.com
Tue Jun 9 09:33:29 UTC 2015


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





More information about the libvir-list mailing list