[libvirt] [PATCH 6/8] qemu: agent: implement function qemuAgetSetMemblocks

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


qemuAgetSetMemblocks() is implemented, according to the qga command:
'guest-set-memory-blocks'.

It asks the guest agent to set memory blocks online/offline according to
the updated MemblockInfo. If all the blocks were setted successfully, the
function returns with success, otherwise, fails.

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 | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_agent.h |   1 +
 2 files changed, 118 insertions(+)

diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
index 2c3a5ba..1945fae 100644
--- a/src/qemu/qemu_agent.c
+++ b/src/qemu/qemu_agent.c
@@ -1846,6 +1846,123 @@ qemuAgentUpdateMemblocks(unsigned long long memory,
 }
 
 int
+qemuAgentSetMemblocks(qemuAgentPtr mon,
+                      qemuAgentMemblockInfoPtr info,
+                      int nblocks)
+{
+    int ret = -1;
+    virJSONValuePtr cmd = NULL;
+    virJSONValuePtr reply = NULL;
+    virJSONValuePtr memblocks = NULL;
+    virJSONValuePtr block = NULL;
+    virJSONValuePtr data = NULL;
+    int size = -1;
+    size_t i;
+
+    /* create the key data array */
+    if (!(memblocks = virJSONValueNewArray()))
+        goto cleanup;
+
+    for (i = 0; i < nblocks; i++) {
+        qemuAgentMemblockInfoPtr in = &info[i];
+
+        /* create single memory block object */
+        if (!(block = virJSONValueNewObject()))
+            goto cleanup;
+
+        if (virJSONValueObjectAppendNumberInt(block, "phys-index", in->id) < 0)
+            goto cleanup;
+
+        if (virJSONValueObjectAppendBoolean(block, "online", in->online) < 0)
+            goto cleanup;
+
+        if (virJSONValueArrayAppend(memblocks, block) < 0)
+            goto cleanup;
+
+        block = NULL;
+    }
+
+    if (!(cmd = qemuAgentMakeCommand("guest-set-memory-blocks",
+                                     "a:mem-blks", memblocks,
+                                     NULL)))
+        goto cleanup;
+
+    memblocks = NULL;
+
+    if (qemuAgentCommand(mon, cmd, &reply, true,
+                         VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0)
+        goto cleanup;
+
+    if (!(data = virJSONValueObjectGet(reply, "return"))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("guest-set-memory-blocks reply was missing return data"));
+        goto cleanup;
+    }
+
+    if (data->type != VIR_JSON_TYPE_ARRAY) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("guest-set-memory-blocks returned information was not "
+                         "an array"));
+        goto cleanup;
+    }
+
+    if ((size = virJSONValueArraySize(data)) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("qemu agent didn't return an array of results"));
+        goto cleanup;
+    }
+
+    for (i = 0; i < size; i++) {
+        virJSONValuePtr tmp_res = virJSONValueArrayGet(data, i);
+        unsigned long long id = 0;
+        const char *response = NULL;
+        int error_code = 0;
+
+        if (!tmp_res) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("qemu agent reply missing result entry in array"));
+            goto cleanup;
+        }
+
+        if (virJSONValueObjectGetNumberUlong(tmp_res, "phys-index", &id) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("qemu agent didn't provide 'phys-index' correctly"));
+            goto cleanup;
+        }
+
+        if (!(response = virJSONValueObjectGetString(tmp_res, "response"))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("qemu agent didn't provide 'response'"
+                             " field for memory block %llu"), id);
+            goto cleanup;
+        }
+
+        if (STRNEQ(response, "success")) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("qemu agent failed to set memory block %llu: %s"), id, response);
+            if (virJSONValueObjectGetNumberInt(tmp_res, "error-code", &error_code) < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("qemu agent didn't provide 'error-code' in response"));
+                goto cleanup;
+            }
+
+            virReportError(VIR_ERR_INTERNAL_ERROR, _("errno-code is %d"), error_code);
+            goto cleanup;
+         }
+    }
+
+    ret = 0;
+
+ cleanup:
+    virJSONValueFree(cmd);
+    virJSONValueFree(reply);
+    virJSONValueFree(block);
+    virJSONValueFree(memblocks);
+    return ret;
+}
+
+
+int
 qemuAgentGetTime(qemuAgentPtr mon,
                  long long *seconds,
                  unsigned int *nseconds)
diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h
index 3ba6deb..9707510 100644
--- a/src/qemu/qemu_agent.h
+++ b/src/qemu/qemu_agent.h
@@ -123,6 +123,7 @@ int qemuAgentUpdateMemblocks(unsigned long long memory,
                              qemuAgentMemblockInfoPtr info,
                              int nblock,
                              unsigned long long blocksize);
+int qemuAgentSetMemblocks(qemuAgentPtr mon, qemuAgentMemblockInfoPtr info, int nblocks);
 
 int qemuAgentGetTime(qemuAgentPtr mon,
                      long long *seconds,
-- 
1.7.12.4





More information about the libvir-list mailing list