5544c1b
From 542fa14530022044ab577c543fba83202d52b703 Mon Sep 17 00:00:00 2001
d4cdad5
From: Amit Shah <amit.shah@redhat.com>
d4cdad5
Date: Mon, 21 Mar 2011 22:05:10 +0100
5544c1b
Subject: [PATCH] char: Throttle when host connection is down#
d4cdad5
d4cdad5
When the host-side connection goes down, throttle the virtio-serial bus
d4cdad5
and later unthrottle when a connection gets established.  This helps
d4cdad5
prevent any lost IO (guest->host) while the host connection was down.
d4cdad5
d4cdad5
Bugzilla: 621484
d4cdad5
d4cdad5
This commit actually helps the bug mentioned above as no writes will now
d4cdad5
get lost because of the throttling done here.  With just the patches
d4cdad5
sent earlier for that bug, one write will end up getting lost in the
d4cdad5
worst case (host d/c, guest write, host connect).
d4cdad5
d4cdad5
Signed-off-by: Amit Shah <amit.shah@redhat.com>
bd56df9
Signed-off-by: Cole Robinson <crobinso@redhat.com>
d4cdad5
---
b6dd5ac
 qemu-char.c | 14 ++++++++++++++
329b588
 1 file changed, 14 insertions(+)
d4cdad5
d4cdad5
diff --git a/qemu-char.c b/qemu-char.c
5544c1b
index 9f8608a..bfc94a5 100644
d4cdad5
--- a/qemu-char.c
d4cdad5
+++ b/qemu-char.c
d4cdad5
@@ -140,6 +140,9 @@ static void qemu_chr_generic_open_bh(void *opaque)
d4cdad5
 {
d4cdad5
     CharDriverState *s = opaque;
d4cdad5
     qemu_chr_be_event(s, CHR_EVENT_OPENED);
d4cdad5
+    if (s->write_blocked) {
d4cdad5
+        char_write_unblocked(s);
d4cdad5
+    }
d4cdad5
     qemu_bh_delete(s->bh);
d4cdad5
     s->bh = NULL;
d4cdad5
 }
5544c1b
@@ -2244,6 +2247,17 @@ static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
d4cdad5
         ret = send_all(chr, s->fd, buf, len);
d4cdad5
         if (ret == -1 && errno == EPIPE) {
d4cdad5
             tcp_closed(chr);
d4cdad5
+
d4cdad5
+            if (chr->chr_enable_write_fd_handler && chr->chr_write_unblocked) {
d4cdad5
+                /*
d4cdad5
+                 * Since we haven't written out anything, let's say
d4cdad5
+                 * we're throttled.  This will prevent any output from
d4cdad5
+                 * the guest getting lost if host-side chardev goes
d4cdad5
+                 * down.  Unthrottle when we re-connect.
d4cdad5
+                 */
d4cdad5
+                chr->write_blocked = true;
d4cdad5
+                return 0;
d4cdad5
+            }
d4cdad5
         }
d4cdad5
         return ret;
d4cdad5
     } else {
d4cdad5
-- 
5544c1b
1.7.12.1
d4cdad5