Patchwork [4/6] Always notify consumers of char devices if they're open

login
register
mail settings
Submitter Alexander Graf
Date April 1, 2010, 4:42 p.m.
Message ID <1270140161-17216-5-git-send-email-agraf@suse.de>
Download mbox | patch
Permalink /patch/49221/
State New
Headers show

Comments

Alexander Graf - April 1, 2010, 4:42 p.m.
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>
---
 qemu-char.c |   20 ++++++++++++++++++++
 qemu-char.h |    1 +
 2 files changed, 21 insertions(+), 0 deletions(-)
Amit Shah - April 5, 2010, 3:43 a.m.
On (Thu) Apr 01 2010 [18:42:39], Alexander Graf wrote:
> 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>

		Amit
Aurelien Jarno - April 9, 2010, 8:09 p.m.
On Thu, Apr 01, 2010 at 06:42:39PM +0200, Alexander Graf wrote:
> 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.

Thanks, applied.

> Signed-off-by: Alexander Graf <agraf@suse.de>
> ---
>  qemu-char.c |   20 ++++++++++++++++++++
>  qemu-char.h |    1 +
>  2 files changed, 21 insertions(+), 0 deletions(-)
> 
> diff --git a/qemu-char.c b/qemu-char.c
> index 6ad6609..a9d9442 100644
> --- a/qemu-char.c
> +++ b/qemu-char.c
> @@ -109,6 +109,16 @@ static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
>  
>  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);
> @@ -193,6 +203,12 @@ void qemu_chr_add_handlers(CharDriverState *s,
>      s->handler_opaque = opaque;
>      if (s->chr_update_read_handler)
>          s->chr_update_read_handler(s);
> +
> +    /* 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)
> @@ -475,6 +491,10 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
>      chr->chr_write = mux_chr_write;
>      chr->chr_update_read_handler = mux_chr_update_read_handler;
>      chr->chr_accept_input = mux_chr_accept_input;
> +
> +    /* Muxes are always open on creation */
> +    qemu_chr_generic_open(chr);
> +
>      return chr;
>  }
>  
> diff --git a/qemu-char.h b/qemu-char.h
> index 3a9427b..e3a0783 100644
> --- a/qemu-char.h
> +++ b/qemu-char.h
> @@ -67,6 +67,7 @@ struct CharDriverState {
>      QEMUBH *bh;
>      char *label;
>      char *filename;
> +    int opened;
>      QTAILQ_ENTRY(CharDriverState) next;
>  };
>  
> -- 
> 1.6.0.2
> 
> 
> 
>

Patch

diff --git a/qemu-char.c b/qemu-char.c
index 6ad6609..a9d9442 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -109,6 +109,16 @@  static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
 
 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);
@@ -193,6 +203,12 @@  void qemu_chr_add_handlers(CharDriverState *s,
     s->handler_opaque = opaque;
     if (s->chr_update_read_handler)
         s->chr_update_read_handler(s);
+
+    /* 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)
@@ -475,6 +491,10 @@  static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
     chr->chr_write = mux_chr_write;
     chr->chr_update_read_handler = mux_chr_update_read_handler;
     chr->chr_accept_input = mux_chr_accept_input;
+
+    /* Muxes are always open on creation */
+    qemu_chr_generic_open(chr);
+
     return chr;
 }
 
diff --git a/qemu-char.h b/qemu-char.h
index 3a9427b..e3a0783 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -67,6 +67,7 @@  struct CharDriverState {
     QEMUBH *bh;
     char *label;
     char *filename;
+    int opened;
     QTAILQ_ENTRY(CharDriverState) next;
 };