Always notify consumers of char devices if they're open
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>
This commit is contained in:
parent
01c0bef162
commit
73cdf3f2c9
20
qemu-char.c
20
qemu-char.c
@ -109,6 +109,16 @@ static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
|
|||||||
|
|
||||||
static void qemu_chr_event(CharDriverState *s, int event)
|
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)
|
if (!s->chr_event)
|
||||||
return;
|
return;
|
||||||
s->chr_event(s->handler_opaque, event);
|
s->chr_event(s->handler_opaque, event);
|
||||||
@ -193,6 +203,12 @@ void qemu_chr_add_handlers(CharDriverState *s,
|
|||||||
s->handler_opaque = opaque;
|
s->handler_opaque = opaque;
|
||||||
if (s->chr_update_read_handler)
|
if (s->chr_update_read_handler)
|
||||||
s->chr_update_read_handler(s);
|
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)
|
static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
|
||||||
@ -465,6 +481,10 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
|
|||||||
chr->chr_write = mux_chr_write;
|
chr->chr_write = mux_chr_write;
|
||||||
chr->chr_update_read_handler = mux_chr_update_read_handler;
|
chr->chr_update_read_handler = mux_chr_update_read_handler;
|
||||||
chr->chr_accept_input = mux_chr_accept_input;
|
chr->chr_accept_input = mux_chr_accept_input;
|
||||||
|
|
||||||
|
/* Muxes are always open on creation */
|
||||||
|
qemu_chr_generic_open(chr);
|
||||||
|
|
||||||
return chr;
|
return chr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ struct CharDriverState {
|
|||||||
QEMUBH *bh;
|
QEMUBH *bh;
|
||||||
char *label;
|
char *label;
|
||||||
char *filename;
|
char *filename;
|
||||||
|
int opened;
|
||||||
QTAILQ_ENTRY(CharDriverState) next;
|
QTAILQ_ENTRY(CharDriverState) next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user