Blame SOURCES/kvm-char-restore-read-callback-on-a-reattached-hotplug-c.patch

eb5a2f
From 3322e336871252ea0ff22920cfb13d302b07bd11 Mon Sep 17 00:00:00 2001
eb5a2f
From: Gal Hammer <ghammer@redhat.com>
eb5a2f
Date: Sun, 16 Mar 2014 09:57:09 +0100
eb5a2f
Subject: [PATCH 28/30] char: restore read callback on a reattached (hotplug) chardev
eb5a2f
eb5a2f
RH-Author: Gal Hammer <ghammer@redhat.com>
eb5a2f
Message-id: <1394963829-5384-1-git-send-email-ghammer@redhat.com>
eb5a2f
Patchwork-id: 58105
eb5a2f
O-Subject: [RHEL-7.0 qemu-kvm PATCH] char: restore read callback on a reattached (hotplug) chardev
eb5a2f
Bugzilla: 1110219
eb5a2f
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
eb5a2f
RH-Acked-by: Amit Shah <amit.shah@redhat.com>
eb5a2f
RH-Acked-by: Amos Kong <akong@redhat.com>
eb5a2f
eb5a2f
Brew: https://brewweb.devel.redhat.com/taskinfo?taskID=7207613
eb5a2f
Upstream: commit ac1b84dd1e020648db82a99260891aa982d1142c
eb5a2f
eb5a2f
Fix a bug that was introduced in commit 386a5a1e. A removal of a device
eb5a2f
set the chr handlers to NULL. However when the device is plugged back,
eb5a2f
its read callback is not restored so data can't be transferred from the
eb5a2f
host to the guest (e.g. via the virtio-serial port).
eb5a2f
eb5a2f
Signed-off-by: Gal Hammer <ghammer@redhat.com>
eb5a2f
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
eb5a2f
---
eb5a2f
 qemu-char.c | 17 +++++++++++++++--
eb5a2f
 1 file changed, 15 insertions(+), 2 deletions(-)
eb5a2f
eb5a2f
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
eb5a2f
---
eb5a2f
 qemu-char.c |   17 +++++++++++++++--
eb5a2f
 1 files changed, 15 insertions(+), 2 deletions(-)
eb5a2f
eb5a2f
diff --git a/qemu-char.c b/qemu-char.c
eb5a2f
index 983f686..930f3d4 100644
eb5a2f
--- a/qemu-char.c
eb5a2f
+++ b/qemu-char.c
eb5a2f
@@ -215,7 +215,7 @@ void qemu_chr_add_handlers(CharDriverState *s,
eb5a2f
     s->chr_read = fd_read;
eb5a2f
     s->chr_event = fd_event;
eb5a2f
     s->handler_opaque = opaque;
eb5a2f
-    if (s->chr_update_read_handler)
eb5a2f
+    if (fe_open && s->chr_update_read_handler)
eb5a2f
         s->chr_update_read_handler(s);
eb5a2f
 
eb5a2f
     if (!s->explicit_fe_open) {
eb5a2f
@@ -1140,13 +1140,14 @@ static void pty_chr_state(CharDriverState *chr, int connected)
eb5a2f
         if (!s->connected) {
eb5a2f
             s->connected = 1;
eb5a2f
             qemu_chr_be_generic_open(chr);
eb5a2f
+        }
eb5a2f
+        if (!chr->fd_in_tag) {
eb5a2f
             chr->fd_in_tag = io_add_watch_poll(s->fd, pty_chr_read_poll,
eb5a2f
                                                pty_chr_read, chr);
eb5a2f
         }
eb5a2f
     }
eb5a2f
 }
eb5a2f
 
eb5a2f
-
eb5a2f
 static void pty_chr_close(struct CharDriverState *chr)
eb5a2f
 {
eb5a2f
     PtyCharDriver *s = chr->opaque;
eb5a2f
@@ -2514,6 +2515,17 @@ static void tcp_chr_connect(void *opaque)
eb5a2f
     qemu_chr_be_generic_open(chr);
eb5a2f
 }
eb5a2f
 
eb5a2f
+static void tcp_chr_update_read_handler(CharDriverState *chr)
eb5a2f
+{
eb5a2f
+    TCPCharDriver *s = chr->opaque;
eb5a2f
+
eb5a2f
+    remove_fd_in_watch(chr);
eb5a2f
+    if (s->chan) {
eb5a2f
+        chr->fd_in_tag = io_add_watch_poll(s->chan, tcp_chr_read_poll,
eb5a2f
+                                           tcp_chr_read, chr);
eb5a2f
+    }
eb5a2f
+}
eb5a2f
+
eb5a2f
 #define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
eb5a2f
 static void tcp_chr_telnet_init(int fd)
eb5a2f
 {
eb5a2f
@@ -2669,6 +2681,7 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
eb5a2f
     chr->get_msgfd = tcp_get_msgfd;
eb5a2f
     chr->chr_add_client = tcp_chr_add_client;
eb5a2f
     chr->chr_add_watch = tcp_chr_add_watch;
eb5a2f
+    chr->chr_update_read_handler = tcp_chr_update_read_handler;
eb5a2f
     /* be isn't opened until we get a connection */
eb5a2f
     chr->explicit_be_open = true;
eb5a2f
 
eb5a2f
-- 
eb5a2f
1.7.1
eb5a2f