Add a /chardevs container object to hold the list of chardevs. (Note: QTAILQ chardevs is going away in the following commits)
Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com> --- include/sysemu/char.h | 3 ++- chardev/char.c | 46 ++++++++++++++++++++++++++++++++++++++-------- gdbstub.c | 2 +- hw/bt/hci-csr.c | 2 +- 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/include/sysemu/char.h b/include/sysemu/char.h index a30ff3fa80..e3f3a10d17 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -490,7 +490,8 @@ typedef struct ChardevClass { } ChardevClass; Chardev *qemu_chardev_new(const char *id, const char *typename, - ChardevBackend *backend, Error **errp); + ChardevBackend *backend, bool enlist, + Error **errp); extern int term_escape_char; diff --git a/chardev/char.c b/chardev/char.c index 9f02c6d5f1..5a12a79c3b 100644 --- a/chardev/char.c +++ b/chardev/char.c @@ -45,6 +45,11 @@ static QTAILQ_HEAD(ChardevHead, Chardev) chardevs = QTAILQ_HEAD_INITIALIZER(chardevs); +static Object *get_chardevs_root(void) +{ + return container_get(object_get_root(), "/chardevs"); +} + void qemu_chr_be_event(Chardev *s, int event) { CharBackend *be = s->be; @@ -804,7 +809,7 @@ static Chardev *qemu_chardev_add(const char *id, const char *typename, return NULL; } - chr = qemu_chardev_new(id, typename, backend, errp); + chr = qemu_chardev_new(id, typename, backend, true, errp); if (!chr) { return NULL; } @@ -1061,8 +1066,14 @@ void qemu_chr_fe_disconnect(CharBackend *be) void qemu_chr_delete(Chardev *chr) { - QTAILQ_REMOVE(&chardevs, chr, next); - object_unref(OBJECT(chr)); + if (QTAILQ_IN_USE(chr, next)) { + QTAILQ_REMOVE(&chardevs, chr, next); + } + if (OBJECT(chr)->parent) { + object_unparent(OBJECT(chr)); + } else { + object_unref(OBJECT(chr)); + } } ChardevInfoList *qmp_query_chardev(Error **errp) @@ -1224,22 +1235,33 @@ void qemu_chr_set_feature(Chardev *chr, } Chardev *qemu_chardev_new(const char *id, const char *typename, - ChardevBackend *backend, Error **errp) + ChardevBackend *backend, bool enlist, + Error **errp) { + Object *obj; Chardev *chr = NULL; Error *local_err = NULL; bool be_opened = true; assert(g_str_has_prefix(typename, "chardev-")); - chr = CHARDEV(object_new(typename)); + if (enlist) { + obj = object_new_with_props(typename, get_chardevs_root(), + id, &local_err, NULL); + } else { + obj = object_new(typename); + } + if (local_err) { + assert(!obj); + goto end; + } + + chr = CHARDEV(obj); chr->label = g_strdup(id); qemu_char_open(chr, backend, &be_opened, &local_err); if (local_err) { - error_propagate(errp, local_err); - object_unref(OBJECT(chr)); - return NULL; + goto end; } if (!chr->filename) { @@ -1249,6 +1271,14 @@ Chardev *qemu_chardev_new(const char *id, const char *typename, qemu_chr_be_event(chr, CHR_EVENT_OPENED); } +end: + if (local_err) { + error_propagate(errp, local_err); + if (chr) { + qemu_chr_delete(chr); + } + return NULL; + } return chr; } diff --git a/gdbstub.c b/gdbstub.c index 755a8e378d..613ac48fed 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1793,7 +1793,7 @@ int gdbserver_start(const char *device) /* Initialize a monitor terminal for gdb */ mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB, - NULL, &error_abort); + NULL, false, &error_abort); monitor_init(mon_chr, 0); } else { if (qemu_chr_fe_get_driver(&s->chr)) { diff --git a/hw/bt/hci-csr.c b/hw/bt/hci-csr.c index 3c193848fc..9c211e89c4 100644 --- a/hw/bt/hci-csr.c +++ b/hw/bt/hci-csr.c @@ -503,7 +503,7 @@ static const TypeInfo char_hci_type_info = { Chardev *uart_hci_init(void) { return qemu_chardev_new(NULL, TYPE_CHARDEV_HCI, - NULL, &error_abort); + NULL, false, &error_abort); } static void register_types(void) -- 2.11.0.295.gd7dffce1c.dirty