char: add a /chardevs container

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.lureau@redhat.com>
This commit is contained in:
Marc-André Lureau 2016-12-14 15:23:36 +03:00
parent f8df5f9221
commit 2f5d45a150
8 changed files with 42 additions and 36 deletions

View file

@ -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;
@ -413,6 +418,9 @@ static void char_finalize(Object *obj)
{
Chardev *chr = CHARDEV(obj);
if (QTAILQ_IN_USE(chr, next)) {
QTAILQ_REMOVE(&chardevs, chr, next);
}
if (chr->be) {
chr->be->chr = NULL;
}
@ -946,7 +954,7 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts,
backend->u.mux.data->chardev = g_strdup(bid);
mux = qemu_chardev_add(id, TYPE_CHARDEV_MUX, backend, errp);
if (mux == NULL) {
qemu_chr_delete(chr);
object_unparent(OBJECT(chr));
chr = NULL;
goto out;
}
@ -1060,12 +1068,6 @@ void qemu_chr_fe_disconnect(CharBackend *be)
}
}
void qemu_chr_delete(Chardev *chr)
{
QTAILQ_REMOVE(&chardevs, chr, next);
object_unref(OBJECT(chr));
}
ChardevInfoList *qmp_query_chardev(Error **errp)
{
ChardevInfoList *chr_list = NULL;
@ -1225,22 +1227,23 @@ void qemu_chr_set_feature(Chardev *chr,
}
Chardev *qemu_chardev_new(const char *id, const char *typename,
ChardevBackend *backend, Error **errp)
ChardevBackend *backend,
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));
obj = object_new(typename);
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) {
@ -1250,6 +1253,21 @@ Chardev *qemu_chardev_new(const char *id, const char *typename,
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
}
if (id) {
object_property_add_child(get_chardevs_root(), id, obj, &local_err);
if (local_err) {
goto end;
}
object_unref(obj);
}
end:
if (local_err) {
error_propagate(errp, local_err);
object_unref(obj);
return NULL;
}
return chr;
}
@ -1298,16 +1316,12 @@ void qmp_chardev_remove(const char *id, Error **errp)
"Chardev '%s' cannot be unplugged in record/replay mode", id);
return;
}
qemu_chr_delete(chr);
object_unparent(OBJECT(chr));
}
void qemu_chr_cleanup(void)
{
Chardev *chr, *tmp;
QTAILQ_FOREACH_SAFE(chr, &chardevs, next, tmp) {
qemu_chr_delete(chr);
}
object_unparent(get_chardevs_root());
}
static void register_types(void)