summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sysemu/char.h1
-rw-r--r--qemu-char.c50
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);