
On Mon, Jun 20, 2016 at 04:34:19PM +0200, Peter Krempa wrote:
Documentation for the "guest-set-vcpus" command describes a proper algorithm how to set vcpus. This patch makes the following changes:
- state of cpus that has not changed is not updated - if the command was partially successful the command is re-tried with the rest of the arguments to get a proper error message - code is more robust against mailicious guest agent
s/mailicious/malicious/
- fix testsuite to the new semantics --- src/qemu/qemu_agent.c | 83 ++++++++++++++++++++++++++++++++++++++++++-------- src/qemu/qemu_agent.h | 2 ++ src/qemu/qemu_driver.c | 13 -------- tests/qemuagenttest.c | 44 ++++++++++++-------------- 4 files changed, 92 insertions(+), 50 deletions(-)
diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c index cbc0995..5bd767a 100644 --- a/src/qemu/qemu_agent.c +++ b/src/qemu/qemu_agent.c @@ -1523,16 +1523,13 @@ qemuAgentGetVCPUs(qemuAgentPtr mon, return ret; }
-/** - * Set the VCPU state using guest agent. - * - * Returns -1 on error, ninfo in case everything was successful and less than - * ninfo on a partial failure. - */ -int -qemuAgentSetVCPUs(qemuAgentPtr mon, - qemuAgentCPUInfoPtr info, - size_t ninfo) + +/* returns the value provided by the guest agent or -1 on internal error */ +static int +qemuAgentSetVCPUsCommand(qemuAgentPtr mon, + qemuAgentCPUInfoPtr info, + size_t ninfo, + int *nmodified) { int ret = -1; virJSONValuePtr cmd = NULL; @@ -1541,6 +1538,8 @@ qemuAgentSetVCPUs(qemuAgentPtr mon, virJSONValuePtr cpu = NULL; size_t i;
+ *nmodified = 0; + /* create the key data array */ if (!(cpus = virJSONValueNewArray())) goto cleanup; @@ -1552,6 +1551,12 @@ qemuAgentSetVCPUs(qemuAgentPtr mon, if (!(cpu = virJSONValueNewObject())) goto cleanup;
+ /* don't set state for cpus that were not touched */ + if (!in->modified) + continue;
This needs to go before the virJSONValueNewObject, otherwise it would leak memory.
+ + (*nmodified)++; + if (virJSONValueObjectAppendNumberInt(cpu, "logical-id", in->id) < 0) goto cleanup;
@@ -1564,6 +1569,11 @@ qemuAgentSetVCPUs(qemuAgentPtr mon, cpu = NULL; }
+ if (*nmodified == 0) { + ret = 0; + goto cleanup; + } + if (!(cmd = qemuAgentMakeCommand("guest-set-vcpus", "a:vcpus", cpus, NULL))) @@ -1575,9 +1585,17 @@ qemuAgentSetVCPUs(qemuAgentPtr mon, VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0) goto cleanup;
- if (virJSONValueObjectGetNumberInt(reply, "return", &ret) < 0) { + if (qemuAgentCheckError(cmd, reply) < 0) + goto cleanup; + + /* All negative values are invalid. Return of 0 is bougs since we wouldn't
s/bougs/bogus/
+ * call the guest agent so that 0 cpus would be set successfully. Reporting + * more successfuly set vcpus that we've asked for is invalid */
s/successfuly/successfully/ s/invalid/invalid./
+ if (virJSONValueObjectGetNumberInt(reply, "return", &ret) < 0 || + ret <= 0 || ret > *nmodified) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("malformed return value")); + _("guest agent returned malformed or invalid return value")); + ret = -1; }
cleanup: @@ -1589,6 +1607,45 @@ qemuAgentSetVCPUs(qemuAgentPtr mon, }
[...] ACK