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