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