diff options
author | Michael Roth <mdroth@linux.vnet.ibm.com> | 2012-02-07 13:56:48 -0600 |
---|---|---|
committer | Michael Roth <mdroth@linux.vnet.ibm.com> | 2012-03-12 15:09:23 -0500 |
commit | 3cf0bed8369267184e5dc5b58882811519d67437 (patch) | |
tree | a9c32d61d08ec7ab795b1b2cc4d74252087e1130 /qga | |
parent | 3424fc9f16a1e7d1c48eb6d605eb0ca63e199ec2 (diff) |
qemu-ga: add guest-sync-delimited
guest-sync leaves it as an exercise to the user as to how to reliably
obtain the response to guest-sync if the client had previously read in a
partial response (due qemu-ga previously being restarted mid-"sentence"
due to reboot, forced restart, etc).
qemu-ga handles this situation on its end by having a client precede
their guest-sync request with a 0xFF byte (invalid UTF-8), which
qemu-ga/QEMU JSON parsers will treat as a flush event. Thus we can
reliably flush the qemu-ga parser state in preparation for receiving
the guest-sync request.
guest-sync-delimited provides the same functionality for a client: when
a guest-sync-delimited is issued, qemu-ga will precede it's response
with a 0xFF byte that the client can use as an indicator to flush its
buffer/parser state in preparation for reliably receiving the
guest-sync-delimited response.
It is also useful as an optimization for clients, since, after issuing a
guest-sync-delimited, clients can safely discard all stale data read
from the channel until the 0xFF is found.
More information available on the wiki:
http://wiki.qemu.org/Features/QAPI/GuestAgent#QEMU_Guest_Agent_Protocol
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Diffstat (limited to 'qga')
-rw-r--r-- | qga/commands-posix.c | 3 | ||||
-rw-r--r-- | qga/commands.c | 6 | ||||
-rw-r--r-- | qga/guest-agent-core.h | 2 |
3 files changed, 8 insertions, 3 deletions
diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 5b77fa9eee..7b2be2f936 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -35,8 +35,6 @@ #include "qemu-queue.h" #include "host-utils.h" -static GAState *ga_state; - static void reopen_fd_to_null(int fd) { int nullfd; @@ -909,7 +907,6 @@ error: /* register init/cleanup routines for stateful command groups */ void ga_command_state_init(GAState *s, GACommandState *cs) { - ga_state = s; #if defined(CONFIG_FSFREEZE) ga_command_state_add(cs, guest_fsfreeze_init, guest_fsfreeze_cleanup); #endif diff --git a/qga/commands.c b/qga/commands.c index b27407d5d7..5bcceaae34 100644 --- a/qga/commands.c +++ b/qga/commands.c @@ -29,6 +29,12 @@ void slog(const gchar *fmt, ...) va_end(ap); } +int64_t qmp_guest_sync_delimited(int64_t id, Error **errp) +{ + ga_set_response_delimited(ga_state); + return id; +} + int64_t qmp_guest_sync(int64_t id, Error **errp) { return id; diff --git a/qga/guest-agent-core.h b/qga/guest-agent-core.h index b5dfa5bbda..304525d3c2 100644 --- a/qga/guest-agent-core.h +++ b/qga/guest-agent-core.h @@ -18,6 +18,7 @@ typedef struct GAState GAState; typedef struct GACommandState GACommandState; +extern GAState *ga_state; void ga_command_state_init(GAState *s, GACommandState *cs); void ga_command_state_add(GACommandState *cs, @@ -30,3 +31,4 @@ bool ga_logging_enabled(GAState *s); void ga_disable_logging(GAState *s); void ga_enable_logging(GAState *s); void slog(const gchar *fmt, ...); +void ga_set_response_delimited(GAState *s); |