
On 10.02.2012 22:25, Eric Blake wrote:
On 02/10/2012 04:25 AM, Michal Privoznik wrote:
via user agent. --- diff to v1: -allow mem and hybrid targets iff system_wakeup monitor command is presented
Before I review too much of this, remember that there is still a pending discussion that might rename the API slightly to add in the wakeup.
src/qemu/qemu_agent.c | 31 +++++++++++++++ src/qemu/qemu_agent.h | 2 + src/qemu/qemu_capabilities.c | 1 + src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_driver.c | 87 ++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor.c | 21 +++++----- src/qemu/qemu_monitor.h | 4 +- src/qemu/qemu_monitor_json.c | 15 ++++--- src/qemu/qemu_monitor_json.h | 5 ++- src/qemu/qemu_process.c | 2 +- 10 files changed, 149 insertions(+), 20 deletions(-)
I'm wondering if it might be worth dividing this into two patches - the first that refactors qemu_capabilities and qemu_monitor to set QEMU_CAPS_WAKEUP, and the second that touches qemu_agent, qemu_driver, and qemu_monitor to wire up the suspend command.
Another thing that would be nice to do would be improving the qemuhelptest.c to allow the testsuite to start probing for JSON responses; I would add some new files qemuhelpdata/qemu-*-monitor, which contains the JSON output corresponding to the query-commands input for the varous qemu versions that support JSON, so we make sure we can enable caps according to what json strings we parse.
Yeah, but I'd like to have this in a separate patch, as it is not trivial and a bit overkill for this functionality I am adding.
+static int +qemuDomainPMSuspendForDuration(virDomainPtr dom, + unsigned int target, + unsigned long long duration, + unsigned int flags) +{ + struct qemud_driver *driver = dom->conn->privateData; + qemuDomainObjPrivatePtr priv; + virDomainObjPtr vm; + int ret = -1; + + virCheckFlags(0, -1); + + if (duration) { + qemuReportError(VIR_ERR_INVALID_ARG, "%s",
VIR_ERR_ARGUMENT_UNSUPPORTED - the call was valid per the documentation, but we don't support it.
+ _("Duration not supported. Use 0 for now")); + return -1; + } + + if (!(target == VIR_NODE_SUSPEND_TARGET_MEM || + target == VIR_NODE_SUSPEND_TARGET_DISK || + target == VIR_NODE_SUSPEND_TARGET_HYBRID)) { + qemuReportError(VIR_ERR_INVALID_ARG,
This one's fine - the call really is invalid per the documentation.
+ + if (priv->agentError) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("QEMU guest agent is not available due to an error")); + goto cleanup; + }
Meta-question - is it right to have a set-once priv->agentError flag? Or, since the agent can come and go at will, an error encountered previously might be overcome if this time around we send a new sync flag. Thus, would it be better to have a dynamic function call, where the task of re-synchronizing to the guest is done at that point, and which either returns 0 if the guest is currently in sync or -1 if the resync failed for any reason? But this would affect all uses of the guest agent, so for now, keeping this call consistent with other callers is okay.
Right. However, we are still pending a patch for issuing 'guest-sync' command which can solve this issue for us. I mean, then we can drop whole priv->agentError;
+ + if (!priv->agent) { + qemuReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", + _("QEMU guest agent is not configured")); + goto cleanup; + }
In fact, if you have a function call, then you could inline the priv->agent check into that function, for less redundancy in all callers that need an active agent.
Agree, but then again - a separate patch.
+ + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) + goto cleanup;
Hmm - if we do have a helper function to resync the agent, it would have to be done inside the job condition.
@@ -1009,19 +1011,16 @@ int qemuMonitorSetCapabilities(qemuMonitorPtr mon)
if (mon->json) { ret = qemuMonitorJSONSetCapabilities(mon); - if (ret == 0) { - int hmp = qemuMonitorJSONCheckHMP(mon); - if (hmp < 0) { - /* qemu may quited unexpectedly when we call - * qemuMonitorJSONCheckHMP() */ - ret = -1; - } else { - mon->json_hmp = hmp > 0; - } - } + if (ret) + goto cleanup; + + ret = qemuMonitorJSONCheckCommands(mon, qemuCaps, &json_hmp); + mon->json_hmp = json_hmp > 0;
Looks nice.
Okay, will send another version. Thanks.