diff options
-rw-r--r-- | include/sysemu/char.h | 1 | ||||
-rw-r--r-- | qemu-char.c | 50 |
2 files changed, 51 insertions, 0 deletions
diff --git a/include/sysemu/char.h b/include/sysemu/char.h index e65e4a4844..8053130a97 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -77,6 +77,7 @@ struct CharDriverState { int explicit_fe_open; int explicit_be_open; int avail_connections; + int is_mux; QemuOpts *opts; QTAILQ_ENTRY(CharDriverState) next; }; diff --git a/qemu-char.c b/qemu-char.c index 3f606c935b..16f3ad77de 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -476,6 +476,46 @@ static void mux_chr_update_read_handler(CharDriverState *chr) mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN); } +static bool muxes_realized; + +/** + * Called after processing of default and command-line-specified + * chardevs to deliver CHR_EVENT_OPENED events to any FEs attached + * to a mux chardev. This is done here to ensure that + * output/prompts/banners are only displayed for the FE that has + * focus when initial command-line processing/machine init is + * completed. + * + * After this point, any new FE attached to any new or existing + * mux will receive CHR_EVENT_OPENED notifications for the BE + * immediately. + */ +static void muxes_realize_done(Notifier *notifier, void *unused) +{ + CharDriverState *chr; + + QTAILQ_FOREACH(chr, &chardevs, next) { + if (chr->is_mux) { + MuxDriver *d = chr->opaque; + int i; + + /* send OPENED to all already-attached FEs */ + for (i = 0; i < d->mux_cnt; i++) { + mux_chr_send_event(d, i, CHR_EVENT_OPENED); + } + /* mark mux as OPENED so any new FEs will immediately receive + * OPENED event + */ + qemu_chr_be_generic_open(chr); + } + } + muxes_realized = true; +} + +static Notifier muxes_realize_notify = { + .notify = muxes_realize_done, +}; + static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) { CharDriverState *chr; @@ -492,6 +532,11 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) chr->chr_accept_input = mux_chr_accept_input; /* Frontend guest-open / -close notification is not support with muxes */ chr->chr_set_fe_open = NULL; + /* only default to opened state if we've realized the initial + * set of muxes + */ + chr->explicit_be_open = muxes_realized ? 0 : 1; + chr->is_mux = 1; return chr; } @@ -3798,6 +3843,11 @@ static void register_types(void) /* Bug-compatibility: */ register_char_driver_qapi("memory", CHARDEV_BACKEND_KIND_MEMORY, qemu_chr_parse_ringbuf); + /* this must be done after machine init, since we register FEs with muxes + * as part of realize functions like serial_isa_realizefn when -nographic + * is specified + */ + qemu_add_machine_init_done_notifier(&muxes_realize_notify); } type_init(register_types); |