aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmit Shah <amit.shah@redhat.com>2011-03-21 22:05:10 +0100
committerDoug Goldstein <cardoe@cardoe.com>2011-07-21 15:17:50 -0500
commit23b8806eb8c9310ea46504740b2cb1fb9331c727 (patch)
treef2cc65b057540f46d608341c60c2e4640e8beaaf
parentchar: Equip the unix/tcp backend to handle nonblocking writes# (diff)
downloadqemu-kvm-23b8806eb8c9310ea46504740b2cb1fb9331c727.tar.gz
qemu-kvm-23b8806eb8c9310ea46504740b2cb1fb9331c727.tar.bz2
qemu-kvm-23b8806eb8c9310ea46504740b2cb1fb9331c727.zip
char: Throttle when host connection is down#
When the host-side connection goes down, throttle the virtio-serial bus and later unthrottle when a connection gets established. This helps prevent any lost IO (guest->host) while the host connection was down. Bugzilla: 621484 This commit actually helps the bug mentioned above as no writes will now get lost because of the throttling done here. With just the patches sent earlier for that bug, one write will end up getting lost in the worst case (host d/c, guest write, host connect). Signed-off-by: Amit Shah <amit.shah@redhat.com>
-rw-r--r--qemu-char.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/qemu-char.c b/qemu-char.c
index 7517f642f..2ef972f26 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -141,6 +141,9 @@ static void qemu_chr_generic_open_bh(void *opaque)
{
CharDriverState *s = opaque;
qemu_chr_event(s, CHR_EVENT_OPENED);
+ if (s->write_blocked) {
+ char_write_unblocked(s);
+ }
qemu_bh_delete(s->bh);
s->bh = NULL;
}
@@ -2025,6 +2028,17 @@ static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
ret = send_all(chr, s->fd, buf, len);
if (ret == -1 && errno == EPIPE) {
tcp_closed(chr);
+
+ if (chr->chr_enable_write_fd_handler && chr->chr_write_unblocked) {
+ /*
+ * Since we haven't written out anything, let's say
+ * we're throttled. This will prevent any output from
+ * the guest getting lost if host-side chardev goes
+ * down. Unthrottle when we re-connect.
+ */
+ chr->write_blocked = true;
+ return 0;
+ }
}
} else {
/* XXX: indicate an error ? */