chardev: introduce chr_machine_done hook

Introduce ChardevClass.chr_machine_done() hook so that chardevs can run
customized procedures after machine init.

There was an existing mux user already that did similar thing but used a
raw machine done notifier.  Generalize it into a framework, and let the
mux chardevs provide such a class-specific hook to achieve the same
thing.  Then we can move the mux related code to the char-mux.c file.

Since at it, replace the mux_realized variable with the global
machine_init_done varible.

This notifier framework will be further leverged by other type of
chardevs soon.

Signed-off-by: Peter Xu <peterx@redhat.com>
Message-Id: <20180306053320.15401-6-peterx@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Peter Xu 2018-03-06 13:33:16 +08:00 committed by Paolo Bonzini
parent ce1230c054
commit c7278b4355
5 changed files with 48 additions and 33 deletions

View file

@ -281,40 +281,31 @@ static const TypeInfo char_type_info = {
.class_init = char_class_init,
};
/**
* 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 int open_muxes(Object *child, void *opaque)
static int chardev_machine_done_notify_one(Object *child, void *opaque)
{
if (CHARDEV_IS_MUX(child)) {
/* send OPENED to all already-attached FEs */
mux_chr_send_all_event(CHARDEV(child), CHR_EVENT_OPENED);
/* mark mux as OPENED so any new FEs will immediately receive
* OPENED event
*/
qemu_chr_be_event(CHARDEV(child), CHR_EVENT_OPENED);
Chardev *chr = (Chardev *)child;
ChardevClass *class = CHARDEV_GET_CLASS(chr);
if (class->chr_machine_done) {
return class->chr_machine_done(chr);
}
return 0;
}
static void muxes_realize_done(Notifier *notifier, void *unused)
static void chardev_machine_done_hook(Notifier *notifier, void *unused)
{
muxes_realized = true;
object_child_foreach(get_chardevs_root(), open_muxes, NULL);
int ret = object_child_foreach(get_chardevs_root(),
chardev_machine_done_notify_one, NULL);
if (ret) {
error_report("Failed to call chardev machine_done hooks");
exit(1);
}
}
static Notifier muxes_realize_notify = {
.notify = muxes_realize_done,
static Notifier chardev_machine_done_notify = {
.notify = chardev_machine_done_hook,
};
static bool qemu_chr_is_busy(Chardev *s)
@ -1118,7 +1109,7 @@ static void register_types(void)
* as part of realize functions like serial_isa_realizefn when -nographic
* is specified
*/
qemu_add_machine_init_done_notifier(&muxes_realize_notify);
qemu_add_machine_init_done_notifier(&chardev_machine_done_notify);
}
type_init(register_types);