From 36bbf6819ea73542d6c89c95f13ccf3117f0cbee Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Thu, 16 Feb 2012 13:52:29 +0100
Subject: [PATCH 001/109] Always notify consumers of char devices if they're
 open

RH-Author: Kevin Wolf <kwolf@redhat.com>
Message-id: <1329400349-12217-1-git-send-email-kwolf@redhat.com>
Patchwork-id: 37395
O-Subject: [RHEL-6.3 qemu-kvm PATCH] Always notify consumers of char devices if they're open
Bugzilla: 791200
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
RH-Acked-by: Amit Shah <amit.shah@redhat.com>
RH-Acked-by: Hans de Goede <hdegoede@redhat.com>

From: Alexander Graf <agraf@suse.de>

Bugzilla: 791200

[ After backporting the coroutine patches, the same problem exists for
other cases; this was found with QMP only opening a connection on a
socket, but not sending a greeting or being responsive at all ]

When using virtio-console on s390, the input doesn't work.

The root of the problem is rather simple. What happens is the following:

 1) create character device for stdio
 2) char device is done creating, sends OPENED event
 3) virtio-console adds handlers
 4) no event comes because the char device is open already
 5) virtio-console doesn't accept input because it didn't
    receive an OPENED event

To make that sure virtio-console gets notified that the character device
is open even when it's been open from the beginning, this patch introduces
a variable that keeps track of the opened state. If the device is open when
the event handlers get installed, we just notify the handler.

This fixes input with virtio-console on s390.

Signed-off-by: Alexander Graf <agraf@suse.de>
Acked-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 73cdf3f2c97703a89b026d3a42c1120ba05fe37d)

Conflicts:

	qemu-char.c
	qemu-char.h

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 qemu-char.c |   19 +++++++++++++++++++
 qemu-char.h |    1 +
 2 files changed, 20 insertions(+), 0 deletions(-)

Signed-off-by: Michal Novotny <minovotn@redhat.com>
---
 qemu-char.c |   19 +++++++++++++++++++
 qemu-char.h |    1 +
 2 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index 9d09d96..a8d6878 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -122,6 +122,16 @@ static void char_write_unblocked(void *opaque)
 
 static void qemu_chr_event(CharDriverState *s, int event)
 {
+    /* Keep track if the char device is open */
+    switch (event) {
+        case CHR_EVENT_OPENED:
+            s->opened = 1;
+            break;
+        case CHR_EVENT_CLOSED:
+            s->opened = 0;
+            break;
+    }
+
     if (!s->chr_event)
         return;
     s->chr_event(s->handler_opaque, event);
@@ -228,6 +238,12 @@ void qemu_chr_add_handlers(CharDriverState *s,
         s->chr_update_read_handler(s);
 
     s->write_blocked = false;
+
+    /* We're connecting to an already opened device, so let's make sure we
+       also get the open event */
+    if (s->opened) {
+        qemu_chr_generic_open(s);
+    }
 }
 
 static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
@@ -509,6 +525,9 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
     chr->chr_guest_open = NULL;
     chr->chr_guest_close = NULL;
 
+    /* Muxes are always open on creation */
+    qemu_chr_generic_open(chr);
+
     return chr;
 }
 
diff --git a/qemu-char.h b/qemu-char.h
index 81bd954..06579d3 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -77,6 +77,7 @@ struct CharDriverState {
     /* Are we in a blocked state? */
     bool write_blocked;
     int avail_connections;
+    int opened;
     QTAILQ_ENTRY(CharDriverState) next;
 };
 
-- 
1.7.7.6

