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:
parent
f8df5f9221
commit
2f5d45a150
@ -45,6 +45,11 @@
|
|||||||
static QTAILQ_HEAD(ChardevHead, Chardev) chardevs =
|
static QTAILQ_HEAD(ChardevHead, Chardev) chardevs =
|
||||||
QTAILQ_HEAD_INITIALIZER(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)
|
void qemu_chr_be_event(Chardev *s, int event)
|
||||||
{
|
{
|
||||||
CharBackend *be = s->be;
|
CharBackend *be = s->be;
|
||||||
@ -413,6 +418,9 @@ static void char_finalize(Object *obj)
|
|||||||
{
|
{
|
||||||
Chardev *chr = CHARDEV(obj);
|
Chardev *chr = CHARDEV(obj);
|
||||||
|
|
||||||
|
if (QTAILQ_IN_USE(chr, next)) {
|
||||||
|
QTAILQ_REMOVE(&chardevs, chr, next);
|
||||||
|
}
|
||||||
if (chr->be) {
|
if (chr->be) {
|
||||||
chr->be->chr = NULL;
|
chr->be->chr = NULL;
|
||||||
}
|
}
|
||||||
@ -946,7 +954,7 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts,
|
|||||||
backend->u.mux.data->chardev = g_strdup(bid);
|
backend->u.mux.data->chardev = g_strdup(bid);
|
||||||
mux = qemu_chardev_add(id, TYPE_CHARDEV_MUX, backend, errp);
|
mux = qemu_chardev_add(id, TYPE_CHARDEV_MUX, backend, errp);
|
||||||
if (mux == NULL) {
|
if (mux == NULL) {
|
||||||
qemu_chr_delete(chr);
|
object_unparent(OBJECT(chr));
|
||||||
chr = NULL;
|
chr = NULL;
|
||||||
goto out;
|
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 *qmp_query_chardev(Error **errp)
|
||||||
{
|
{
|
||||||
ChardevInfoList *chr_list = NULL;
|
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,
|
Chardev *qemu_chardev_new(const char *id, const char *typename,
|
||||||
ChardevBackend *backend, Error **errp)
|
ChardevBackend *backend,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
|
Object *obj;
|
||||||
Chardev *chr = NULL;
|
Chardev *chr = NULL;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
bool be_opened = true;
|
bool be_opened = true;
|
||||||
|
|
||||||
assert(g_str_has_prefix(typename, "chardev-"));
|
assert(g_str_has_prefix(typename, "chardev-"));
|
||||||
|
|
||||||
chr = CHARDEV(object_new(typename));
|
obj = object_new(typename);
|
||||||
|
chr = CHARDEV(obj);
|
||||||
chr->label = g_strdup(id);
|
chr->label = g_strdup(id);
|
||||||
|
|
||||||
qemu_char_open(chr, backend, &be_opened, &local_err);
|
qemu_char_open(chr, backend, &be_opened, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(errp, local_err);
|
goto end;
|
||||||
object_unref(OBJECT(chr));
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!chr->filename) {
|
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);
|
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;
|
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);
|
"Chardev '%s' cannot be unplugged in record/replay mode", id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qemu_chr_delete(chr);
|
object_unparent(OBJECT(chr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void qemu_chr_cleanup(void)
|
void qemu_chr_cleanup(void)
|
||||||
{
|
{
|
||||||
Chardev *chr, *tmp;
|
object_unparent(get_chardevs_root());
|
||||||
|
|
||||||
QTAILQ_FOREACH_SAFE(chr, &chardevs, next, tmp) {
|
|
||||||
qemu_chr_delete(chr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void register_types(void)
|
static void register_types(void)
|
||||||
|
@ -1611,7 +1611,7 @@ void gdb_exit(CPUArchState *env, int code)
|
|||||||
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
qemu_chr_fe_deinit(&s->chr);
|
qemu_chr_fe_deinit(&s->chr);
|
||||||
qemu_chr_delete(chr);
|
object_unparent(OBJECT(chr));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1912,7 +1912,7 @@ int gdbserver_start(const char *device)
|
|||||||
monitor_init(mon_chr, 0);
|
monitor_init(mon_chr, 0);
|
||||||
} else {
|
} else {
|
||||||
if (qemu_chr_fe_get_driver(&s->chr)) {
|
if (qemu_chr_fe_get_driver(&s->chr)) {
|
||||||
qemu_chr_delete(qemu_chr_fe_get_driver(&s->chr));
|
object_unparent(OBJECT(qemu_chr_fe_get_driver(&s->chr)));
|
||||||
}
|
}
|
||||||
mon_chr = s->mon_chr;
|
mon_chr = s->mon_chr;
|
||||||
memset(s, 0, sizeof(GDBState));
|
memset(s, 0, sizeof(GDBState));
|
||||||
|
@ -267,7 +267,7 @@ static void ccid_card_vscard_drop_connection(PassthruState *card)
|
|||||||
Chardev *chr = qemu_chr_fe_get_driver(&card->cs);
|
Chardev *chr = qemu_chr_fe_get_driver(&card->cs);
|
||||||
|
|
||||||
qemu_chr_fe_deinit(&card->cs);
|
qemu_chr_fe_deinit(&card->cs);
|
||||||
qemu_chr_delete(chr);
|
object_unparent(OBJECT(chr));
|
||||||
card->vscard_in_pos = card->vscard_in_hdr = 0;
|
card->vscard_in_pos = card->vscard_in_hdr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1433,7 +1433,7 @@ static void usbredir_unrealize(USBDevice *udev, Error **errp)
|
|||||||
Chardev *chr = qemu_chr_fe_get_driver(&dev->cs);
|
Chardev *chr = qemu_chr_fe_get_driver(&dev->cs);
|
||||||
|
|
||||||
qemu_chr_fe_deinit(&dev->cs);
|
qemu_chr_fe_deinit(&dev->cs);
|
||||||
qemu_chr_delete(chr);
|
object_unparent(OBJECT(chr));
|
||||||
|
|
||||||
/* Note must be done after qemu_chr_close, as that causes a close event */
|
/* Note must be done after qemu_chr_close, as that causes a close event */
|
||||||
qemu_bh_delete(dev->chardev_close_bh);
|
qemu_bh_delete(dev->chardev_close_bh);
|
||||||
|
@ -170,14 +170,6 @@ int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp);
|
|||||||
*/
|
*/
|
||||||
Chardev *qemu_chr_new_noreplay(const char *label, const char *filename);
|
Chardev *qemu_chr_new_noreplay(const char *label, const char *filename);
|
||||||
|
|
||||||
/**
|
|
||||||
* @qemu_chr_delete:
|
|
||||||
*
|
|
||||||
* Destroy a character backend and remove it from the list of
|
|
||||||
* identified character backends.
|
|
||||||
*/
|
|
||||||
void qemu_chr_delete(Chardev *chr);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @qemu_chr_fe_set_echo:
|
* @qemu_chr_fe_set_echo:
|
||||||
*
|
*
|
||||||
|
@ -154,7 +154,7 @@ static void vhost_user_cleanup(NetClientState *nc)
|
|||||||
Chardev *chr = qemu_chr_fe_get_driver(&s->chr);
|
Chardev *chr = qemu_chr_fe_get_driver(&s->chr);
|
||||||
|
|
||||||
qemu_chr_fe_deinit(&s->chr);
|
qemu_chr_fe_deinit(&s->chr);
|
||||||
qemu_chr_delete(chr);
|
object_unparent(OBJECT(chr));
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_purge_queued_packets(nc);
|
qemu_purge_queued_packets(nc);
|
||||||
|
@ -53,7 +53,7 @@ static void char_stdio_test_subprocess(void)
|
|||||||
g_assert_cmpint(ret, ==, 4);
|
g_assert_cmpint(ret, ==, 4);
|
||||||
|
|
||||||
qemu_chr_fe_deinit(&be);
|
qemu_chr_fe_deinit(&be);
|
||||||
qemu_chr_delete(chr);
|
object_unparent(OBJECT(chr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void char_stdio_test(void)
|
static void char_stdio_test(void)
|
||||||
@ -103,7 +103,7 @@ static void char_ringbuf_test(void)
|
|||||||
g_free(data);
|
g_free(data);
|
||||||
|
|
||||||
qemu_chr_fe_deinit(&be);
|
qemu_chr_fe_deinit(&be);
|
||||||
qemu_chr_delete(chr);
|
object_unparent(OBJECT(chr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void char_mux_test(void)
|
static void char_mux_test(void)
|
||||||
@ -179,7 +179,7 @@ static void char_mux_test(void)
|
|||||||
|
|
||||||
qemu_chr_fe_deinit(&chr_be1);
|
qemu_chr_fe_deinit(&chr_be1);
|
||||||
qemu_chr_fe_deinit(&chr_be2);
|
qemu_chr_fe_deinit(&chr_be2);
|
||||||
qemu_chr_delete(chr);
|
object_unparent(OBJECT(chr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void char_null_test(void)
|
static void char_null_test(void)
|
||||||
@ -222,7 +222,7 @@ static void char_null_test(void)
|
|||||||
g_assert_cmpint(ret, ==, 4);
|
g_assert_cmpint(ret, ==, 4);
|
||||||
|
|
||||||
qemu_chr_fe_deinit(&be);
|
qemu_chr_fe_deinit(&be);
|
||||||
qemu_chr_delete(chr);
|
object_unparent(OBJECT(chr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void char_invalid_test(void)
|
static void char_invalid_test(void)
|
||||||
|
@ -491,7 +491,7 @@ static gboolean _test_server_free(TestServer *server)
|
|||||||
Chardev *chr = qemu_chr_fe_get_driver(&server->chr);
|
Chardev *chr = qemu_chr_fe_get_driver(&server->chr);
|
||||||
|
|
||||||
qemu_chr_fe_deinit(&server->chr);
|
qemu_chr_fe_deinit(&server->chr);
|
||||||
qemu_chr_delete(chr);
|
object_unparent(OBJECT(chr));
|
||||||
|
|
||||||
for (i = 0; i < server->fds_num; i++) {
|
for (i = 0; i < server->fds_num; i++) {
|
||||||
close(server->fds[i]);
|
close(server->fds[i]);
|
||||||
|
Loading…
Reference in New Issue
Block a user