All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9)
@ 2017-03-16  9:21 Marc-André Lureau
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 01/21] char: remove qemu_chr_be_generic_open Marc-André Lureau
                   ` (21 more replies)
  0 siblings, 22 replies; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

Hi,

The following series contains various patches:
- replace "chardevs" list for a /chardevs container object
- add a few read-only socket properties mainly useful for testing
- some chardev related clean-ups
- add various chardev tests

This series is part of a larger refactoring series that I try to keep
up to date here: https://github.com/elmarco/qemu/commits/chrfe

v3:
- open code object_new_with_props() as suggest by Paolo
- added some r-b tags
- rebased

v2:
- replaced root container unref with a TODO
- call object_unparent() directly instead of qemu_chr_delete()
- remove bad qcow2 NULL check removal
- rebased

Marc-André Lureau (21):
  char: remove qemu_chr_be_generic_open
  mux: simplfy muxes_realize_done
  xen: use a better chardev type check
  container: don't leak container reference
  char: add a /chardevs container
  vl: add todo note about root container cleanup
  char: use /chardevs container instead of chardevs list
  char: remove qemu_chardev_add
  char: remove chardevs list
  char: useless NULL check
  char-socket: introduce update_disconnected_filename()
  char-socket: update local address after listen
  char-socket: add 'addr' property
  char-socket: add 'connected' property
  char-udp: flush as much buffer as possible
  tests: add alias check in /char/ringbuf
  tests: add /char/pipe test
  tests: add /char/file test
  tests: add /char/socket test
  tests: add /char/udp test
  tests: add /char/console test

 chardev/char-mux.h          |   2 +-
 include/sysemu/char.h       |  10 --
 chardev/char-mux.c          |  11 +-
 chardev/char-pty.c          |   2 +-
 chardev/char-socket.c       |  46 +++++-
 chardev/char-udp.c          |  26 ++--
 chardev/char.c              | 148 ++++++++----------
 gdbstub.c                   |   4 +-
 hw/usb/ccid-card-passthru.c |   2 +-
 hw/usb/redirect.c           |   2 +-
 net/vhost-user.c            |   2 +-
 qom/container.c             |   1 +
 tests/test-char.c           | 366 +++++++++++++++++++++++++++++++++++++++++++-
 tests/vhost-user-test.c     |   2 +-
 ui/console.c                |   2 +-
 ui/gtk.c                    |   2 +-
 vl.c                        |   1 +
 xen-common.c                |   2 +-
 18 files changed, 504 insertions(+), 127 deletions(-)

-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 01/21] char: remove qemu_chr_be_generic_open
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-04-04 15:08   ` Philippe Mathieu-Daudé
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 02/21] mux: simplfy muxes_realize_done Marc-André Lureau
                   ` (20 subsequent siblings)
  21 siblings, 1 reply; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

The function simply alias and hides the real event function.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 include/sysemu/char.h |  1 -
 chardev/char-pty.c    |  2 +-
 chardev/char-socket.c |  2 +-
 chardev/char.c        | 10 ++--------
 ui/console.c          |  2 +-
 ui/gtk.c              |  2 +-
 6 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index 450881d42c..a30ff3fa80 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -427,7 +427,6 @@ void qemu_chr_fe_set_handlers(CharBackend *b,
  */
 void qemu_chr_fe_take_focus(CharBackend *b);
 
-void qemu_chr_be_generic_open(Chardev *s);
 void qemu_chr_fe_accept_input(CharBackend *be);
 int qemu_chr_add_client(Chardev *s, int fd);
 Chardev *qemu_chr_find(const char *name);
diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index a6337be8aa..aa9d0cb2c3 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -185,7 +185,7 @@ static gboolean qemu_chr_be_generic_open_func(gpointer opaque)
     PtyChardev *s = PTY_CHARDEV(opaque);
 
     s->open_tag = 0;
-    qemu_chr_be_generic_open(chr);
+    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
     return FALSE;
 }
 
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index d7e92e1bd3..dc3d3532a7 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -486,7 +486,7 @@ static void tcp_chr_connect(void *opaque)
                                            tcp_chr_read,
                                            chr, NULL);
     }
-    qemu_chr_be_generic_open(chr);
+    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 }
 
 static void tcp_chr_update_read_handler(Chardev *chr,
diff --git a/chardev/char.c b/chardev/char.c
index 3df116350b..aad639b620 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -66,12 +66,6 @@ void qemu_chr_be_event(Chardev *s, int event)
     be->chr_event(be->opaque, event);
 }
 
-void qemu_chr_be_generic_open(Chardev *s)
-{
-    qemu_chr_be_event(s, CHR_EVENT_OPENED);
-}
-
-
 /* Not reporting errors from writing to logfile, as logs are
  * defined to be "best effort" only */
 static void qemu_chr_fe_write_log(Chardev *s,
@@ -469,7 +463,7 @@ static void muxes_realize_done(Notifier *notifier, void *unused)
             /* mark mux as OPENED so any new FEs will immediately receive
              * OPENED event
              */
-            qemu_chr_be_generic_open(chr);
+            qemu_chr_be_event(chr, CHR_EVENT_OPENED);
         }
     }
     muxes_realized = true;
@@ -581,7 +575,7 @@ void qemu_chr_fe_set_handlers(CharBackend *b,
         /* We're connecting to an already opened device, so let's make sure we
            also get the open event */
         if (s->be_open) {
-            qemu_chr_be_generic_open(s);
+            qemu_chr_be_event(s, CHR_EVENT_OPENED);
         }
     }
 
diff --git a/ui/console.c b/ui/console.c
index d1ff7504ec..d88c52efe5 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -2070,7 +2070,7 @@ static void text_console_do_init(Chardev *chr, DisplayState *ds)
         s->t_attrib = s->t_attrib_default;
     }
 
-    qemu_chr_be_generic_open(chr);
+    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 }
 
 static void vc_chr_open(Chardev *chr,
diff --git a/ui/gtk.c b/ui/gtk.c
index a86848f3b0..7479ceef35 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1868,7 +1868,7 @@ static GSList *gd_vc_vte_init(GtkDisplayState *s, VirtualConsole *vc,
     gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook), vc->tab_item,
                              gtk_label_new(vc->label));
 
-    qemu_chr_be_generic_open(vc->vte.chr);
+    qemu_chr_be_event(vc->vte.chr, CHR_EVENT_OPENED);
 
     return group;
 }
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 02/21] mux: simplfy muxes_realize_done
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 01/21] char: remove qemu_chr_be_generic_open Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-04-04 15:14   ` Philippe Mathieu-Daudé
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 03/21] xen: use a better chardev type check Marc-André Lureau
                   ` (19 subsequent siblings)
  21 siblings, 1 reply; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

mux_chr_event() already send events to all backends, rename it,
export it, and use it from muxes_realize_done. This should help abstract
away mux implementation.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 chardev/char-mux.h |  2 +-
 chardev/char-mux.c | 11 ++++++++---
 chardev/char.c     |  9 ++-------
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/chardev/char-mux.h b/chardev/char-mux.h
index 9a2fffce91..3f41dfcfd2 100644
--- a/chardev/char-mux.h
+++ b/chardev/char-mux.h
@@ -58,6 +58,6 @@ typedef struct MuxChardev {
 
 void mux_chr_set_handlers(Chardev *chr, GMainContext *context);
 void mux_set_focus(Chardev *chr, int focus);
-void mux_chr_send_event(MuxChardev *d, int mux_nr, int event);
+void mux_chr_send_all_event(Chardev *chr, int event);
 
 #endif /* CHAR_MUX_H */
diff --git a/chardev/char-mux.c b/chardev/char-mux.c
index 5547a36a0a..37d42c65c6 100644
--- a/chardev/char-mux.c
+++ b/chardev/char-mux.c
@@ -114,7 +114,7 @@ static void mux_print_help(Chardev *chr)
     }
 }
 
-void mux_chr_send_event(MuxChardev *d, int mux_nr, int event)
+static void mux_chr_send_event(MuxChardev *d, int mux_nr, int event)
 {
     CharBackend *be = d->backends[mux_nr];
 
@@ -222,9 +222,9 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
 
 bool muxes_realized;
 
-static void mux_chr_event(void *opaque, int event)
+void mux_chr_send_all_event(Chardev *chr, int event)
 {
-    MuxChardev *d = MUX_CHARDEV(opaque);
+    MuxChardev *d = MUX_CHARDEV(chr);
     int i;
 
     if (!muxes_realized) {
@@ -237,6 +237,11 @@ static void mux_chr_event(void *opaque, int event)
     }
 }
 
+static void mux_chr_event(void *opaque, int event)
+{
+    mux_chr_send_all_event(CHARDEV(opaque), event);
+}
+
 static GSource *mux_chr_add_watch(Chardev *s, GIOCondition cond)
 {
     MuxChardev *d = MUX_CHARDEV(s);
diff --git a/chardev/char.c b/chardev/char.c
index aad639b620..674c097fbe 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -451,22 +451,17 @@ static void muxes_realize_done(Notifier *notifier, void *unused)
 {
     Chardev *chr;
 
+    muxes_realized = true;
     QTAILQ_FOREACH(chr, &chardevs, next) {
         if (CHARDEV_IS_MUX(chr)) {
-            MuxChardev *d = MUX_CHARDEV(chr);
-            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);
-            }
+            mux_chr_send_all_event(CHARDEV(chr), CHR_EVENT_OPENED);
             /* mark mux as OPENED so any new FEs will immediately receive
              * OPENED event
              */
             qemu_chr_be_event(chr, CHR_EVENT_OPENED);
         }
     }
-    muxes_realized = true;
 }
 
 static Notifier muxes_realize_notify = {
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 03/21] xen: use a better chardev type check
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 01/21] char: remove qemu_chr_be_generic_open Marc-André Lureau
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 02/21] mux: simplfy muxes_realize_done Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-04-04 15:15   ` Philippe Mathieu-Daudé
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 04/21] container: don't leak container reference Marc-André Lureau
                   ` (18 subsequent siblings)
  21 siblings, 1 reply; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 xen-common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen-common.c b/xen-common.c
index fd2c92847e..d46685ef4e 100644
--- a/xen-common.c
+++ b/xen-common.c
@@ -34,7 +34,7 @@ static int store_dev_info(int domid, Chardev *cs, const char *string)
     int ret = -1;
 
     /* Only continue if we're talking to a pty. */
-    if (strncmp(cs->filename, "pty:", 4)) {
+    if (!CHARDEV_IS_PTY(cs)) {
         return 0;
     }
     pts = cs->filename + 4;
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 04/21] container: don't leak container reference
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (2 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 03/21] xen: use a better chardev type check Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-04-11  2:53   ` Philippe Mathieu-Daudé
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 05/21] char: add a /chardevs container Marc-André Lureau
                   ` (17 subsequent siblings)
  21 siblings, 1 reply; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

object_property_add_child() references the child, unref it after to
avoid ref leaks.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 qom/container.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/qom/container.c b/qom/container.c
index c9eb49b01e..f6ccaf7ea7 100644
--- a/qom/container.c
+++ b/qom/container.c
@@ -40,6 +40,7 @@ Object *container_get(Object *root, const char *path)
         if (!child) {
             child = object_new("container");
             object_property_add_child(obj, parts[i], child, NULL);
+            object_unref(child);
         }
     }
 
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 05/21] char: add a /chardevs container
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (3 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 04/21] container: don't leak container reference Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 06/21] vl: add todo note about root container cleanup Marc-André Lureau
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

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>
---
 include/sysemu/char.h       |  8 --------
 chardev/char.c              | 50 +++++++++++++++++++++++++++++----------------
 gdbstub.c                   |  4 ++--
 hw/usb/ccid-card-passthru.c |  2 +-
 hw/usb/redirect.c           |  2 +-
 net/vhost-user.c            |  2 +-
 tests/test-char.c           |  8 ++++----
 tests/vhost-user-test.c     |  2 +-
 8 files changed, 42 insertions(+), 36 deletions(-)

diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index a30ff3fa80..98903f31e4 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -171,14 +171,6 @@ int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp);
 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:
  *
  * Ask the backend to override its normal echo setting.  This only really
diff --git a/chardev/char.c b/chardev/char.c
index 674c097fbe..5456fb2e3a 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;
@@ -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)
diff --git a/gdbstub.c b/gdbstub.c
index 991115361e..07ebfe9626 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1611,7 +1611,7 @@ void gdb_exit(CPUArchState *env, int code)
 
 #ifndef CONFIG_USER_ONLY
   qemu_chr_fe_deinit(&s->chr);
-  qemu_chr_delete(chr);
+  object_unparent(OBJECT(chr));
 #endif
 }
 
@@ -1912,7 +1912,7 @@ int gdbserver_start(const char *device)
         monitor_init(mon_chr, 0);
     } else {
         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;
         memset(s, 0, sizeof(GDBState));
diff --git a/hw/usb/ccid-card-passthru.c b/hw/usb/ccid-card-passthru.c
index daab0d56cf..a41b0d6ec5 100644
--- a/hw/usb/ccid-card-passthru.c
+++ b/hw/usb/ccid-card-passthru.c
@@ -267,7 +267,7 @@ static void ccid_card_vscard_drop_connection(PassthruState *card)
     Chardev *chr = qemu_chr_fe_get_driver(&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;
 }
 
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 0efe62f725..b001a27f05 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1433,7 +1433,7 @@ static void usbredir_unrealize(USBDevice *udev, Error **errp)
     Chardev *chr = qemu_chr_fe_get_driver(&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 */
     qemu_bh_delete(dev->chardev_close_bh);
diff --git a/net/vhost-user.c b/net/vhost-user.c
index e7e63408a1..00a0c1cbc5 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -154,7 +154,7 @@ static void vhost_user_cleanup(NetClientState *nc)
         Chardev *chr = qemu_chr_fe_get_driver(&s->chr);
 
         qemu_chr_fe_deinit(&s->chr);
-        qemu_chr_delete(chr);
+        object_unparent(OBJECT(chr));
     }
 
     qemu_purge_queued_packets(nc);
diff --git a/tests/test-char.c b/tests/test-char.c
index da69f110e4..71de4b35ee 100644
--- a/tests/test-char.c
+++ b/tests/test-char.c
@@ -53,7 +53,7 @@ static void char_stdio_test_subprocess(void)
     g_assert_cmpint(ret, ==, 4);
 
     qemu_chr_fe_deinit(&be);
-    qemu_chr_delete(chr);
+    object_unparent(OBJECT(chr));
 }
 
 static void char_stdio_test(void)
@@ -103,7 +103,7 @@ static void char_ringbuf_test(void)
     g_free(data);
 
     qemu_chr_fe_deinit(&be);
-    qemu_chr_delete(chr);
+    object_unparent(OBJECT(chr));
 }
 
 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_be2);
-    qemu_chr_delete(chr);
+    object_unparent(OBJECT(chr));
 }
 
 static void char_null_test(void)
@@ -222,7 +222,7 @@ static void char_null_test(void)
     g_assert_cmpint(ret, ==, 4);
 
     qemu_chr_fe_deinit(&be);
-    qemu_chr_delete(chr);
+    object_unparent(OBJECT(chr));
 }
 
 static void char_invalid_test(void)
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index a61896c32d..9095af267e 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -491,7 +491,7 @@ static gboolean _test_server_free(TestServer *server)
     Chardev *chr = qemu_chr_fe_get_driver(&server->chr);
 
     qemu_chr_fe_deinit(&server->chr);
-    qemu_chr_delete(chr);
+    object_unparent(OBJECT(chr));
 
     for (i = 0; i < server->fds_num; i++) {
         close(server->fds[i]);
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 06/21] vl: add todo note about root container cleanup
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (4 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 05/21] char: add a /chardevs container Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 07/21] char: use /chardevs container instead of chardevs list Marc-André Lureau
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 vl.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/vl.c b/vl.c
index 0b4ed5241c..5440e1eb47 100644
--- a/vl.c
+++ b/vl.c
@@ -4719,6 +4719,7 @@ int main(int argc, char **argv, char **envp)
     audio_cleanup();
     monitor_cleanup();
     qemu_chr_cleanup();
+    /* TODO: unref root container, check all devices are ok */
 
     return 0;
 }
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 07/21] char: use /chardevs container instead of chardevs list
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (5 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 06/21] vl: add todo note about root container cleanup Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 08/21] char: remove qemu_chardev_add Marc-André Lureau
                   ` (14 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

Use object_resolve_path_component() and object_child_foreach() on
/chardevs container instead of iterating over chardevs list.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 chardev/char.c | 66 ++++++++++++++++++++++++++++++++--------------------------
 1 file changed, 36 insertions(+), 30 deletions(-)

diff --git a/chardev/char.c b/chardev/char.c
index 5456fb2e3a..1859680bea 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -455,21 +455,24 @@ static const TypeInfo char_type_info = {
  * mux will receive CHR_EVENT_OPENED notifications for the BE
  * immediately.
  */
-static void muxes_realize_done(Notifier *notifier, void *unused)
+static int open_muxes(Object *child, void *opaque)
 {
-    Chardev *chr;
+    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);
+    }
 
+    return 0;
+}
+
+static void muxes_realize_done(Notifier *notifier, void *unused)
+{
     muxes_realized = true;
-    QTAILQ_FOREACH(chr, &chardevs, next) {
-        if (CHARDEV_IS_MUX(chr)) {
-            /* send OPENED to all already-attached FEs */
-            mux_chr_send_all_event(CHARDEV(chr), CHR_EVENT_OPENED);
-            /* mark mux as OPENED so any new FEs will immediately receive
-             * OPENED event
-             */
-            qemu_chr_be_event(chr, CHR_EVENT_OPENED);
-        }
-    }
+    object_child_foreach(get_chardevs_root(), open_muxes, NULL);
 }
 
 static Notifier muxes_realize_notify = {
@@ -1068,21 +1071,29 @@ void qemu_chr_fe_disconnect(CharBackend *be)
     }
 }
 
+static int qmp_query_chardev_foreach(Object *obj, void *data)
+{
+    Chardev *chr = CHARDEV(obj);
+    ChardevInfoList **list = data;
+    ChardevInfoList *info = g_malloc0(sizeof(*info));
+
+    info->value = g_malloc0(sizeof(*info->value));
+    info->value->label = g_strdup(chr->label);
+    info->value->filename = g_strdup(chr->filename);
+    info->value->frontend_open = chr->be && chr->be->fe_open;
+
+    info->next = *list;
+    *list = info;
+
+    return 0;
+}
+
 ChardevInfoList *qmp_query_chardev(Error **errp)
 {
     ChardevInfoList *chr_list = NULL;
-    Chardev *chr;
-
-    QTAILQ_FOREACH(chr, &chardevs, next) {
-        ChardevInfoList *info = g_malloc0(sizeof(*info));
-        info->value = g_malloc0(sizeof(*info->value));
-        info->value->label = g_strdup(chr->label);
-        info->value->filename = g_strdup(chr->filename);
-        info->value->frontend_open = chr->be && chr->be->fe_open;
 
-        info->next = chr_list;
-        chr_list = info;
-    }
+    object_child_foreach(get_chardevs_root(),
+                         qmp_query_chardev_foreach, &chr_list);
 
     return chr_list;
 }
@@ -1110,14 +1121,9 @@ ChardevBackendInfoList *qmp_query_chardev_backends(Error **errp)
 
 Chardev *qemu_chr_find(const char *name)
 {
-    Chardev *chr;
+    Object *obj = object_resolve_path_component(get_chardevs_root(), name);
 
-    QTAILQ_FOREACH(chr, &chardevs, next) {
-        if (strcmp(chr->label, name) != 0)
-            continue;
-        return chr;
-    }
-    return NULL;
+    return obj ? CHARDEV(obj) : NULL;
 }
 
 QemuOptsList qemu_chardev_opts = {
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 08/21] char: remove qemu_chardev_add
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (6 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 07/21] char: use /chardevs container instead of chardevs list Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 09/21] char: remove chardevs list Marc-André Lureau
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

qemu_chardev_new() now uses object_new_with_props() with /chardevs
parent container. It will fail to insert the object if the same "id"
already exists. "chardevs" list usage has been removed in previous
commits.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 chardev/char.c | 27 ++++-----------------------
 1 file changed, 4 insertions(+), 23 deletions(-)

diff --git a/chardev/char.c b/chardev/char.c
index 1859680bea..276d27f403 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -805,26 +805,6 @@ static const ChardevClass *char_get_class(const char *driver, Error **errp)
     return cc;
 }
 
-static Chardev *qemu_chardev_add(const char *id, const char *typename,
-                                 ChardevBackend *backend, Error **errp)
-{
-    Chardev *chr;
-
-    chr = qemu_chr_find(id);
-    if (chr) {
-        error_setg(errp, "Chardev '%s' already exists", id);
-        return NULL;
-    }
-
-    chr = qemu_chardev_new(id, typename, backend, errp);
-    if (!chr) {
-        return NULL;
-    }
-
-    QTAILQ_INSERT_TAIL(&chardevs, chr, next);
-    return chr;
-}
-
 static const struct ChardevAlias {
     const char *typename;
     const char *alias;
@@ -941,9 +921,10 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts,
         backend->u.null.data = ccom; /* Any ChardevCommon member would work */
     }
 
-    chr = qemu_chardev_add(bid ? bid : id,
+    chr = qemu_chardev_new(bid ? bid : id,
                            object_class_get_name(OBJECT_CLASS(cc)),
                            backend, errp);
+
     if (chr == NULL) {
         goto out;
     }
@@ -955,7 +936,7 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts,
         backend->type = CHARDEV_BACKEND_KIND_MUX;
         backend->u.mux.data = g_new0(ChardevMux, 1);
         backend->u.mux.data->chardev = g_strdup(bid);
-        mux = qemu_chardev_add(id, TYPE_CHARDEV_MUX, backend, errp);
+        mux = qemu_chardev_new(id, TYPE_CHARDEV_MUX, backend, errp);
         if (mux == NULL) {
             object_unparent(OBJECT(chr));
             chr = NULL;
@@ -1289,7 +1270,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
         return NULL;
     }
 
-    chr = qemu_chardev_add(id, object_class_get_name(OBJECT_CLASS(cc)),
+    chr = qemu_chardev_new(id, object_class_get_name(OBJECT_CLASS(cc)),
                            backend, errp);
     if (!chr) {
         return NULL;
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 09/21] char: remove chardevs list
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (7 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 08/21] char: remove qemu_chardev_add Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 10/21] char: useless NULL check Marc-André Lureau
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

The list is now empty, the chardev cleanup is taken care of by the unref
of the root container.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/sysemu/char.h | 1 -
 chardev/char.c        | 6 ------
 2 files changed, 7 deletions(-)

diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index 98903f31e4..729d186d01 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -95,7 +95,6 @@ struct Chardev {
     int be_open;
     guint fd_in_tag;
     DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST);
-    QTAILQ_ENTRY(Chardev) next;
 };
 
 /**
diff --git a/chardev/char.c b/chardev/char.c
index 276d27f403..aee8b4555d 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -42,9 +42,6 @@
 /***********************************************************/
 /* character device */
 
-static QTAILQ_HEAD(ChardevHead, Chardev) chardevs =
-    QTAILQ_HEAD_INITIALIZER(chardevs);
-
 static Object *get_chardevs_root(void)
 {
     return container_get(object_get_root(), "/chardevs");
@@ -418,9 +415,6 @@ 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;
     }
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 10/21] char: useless NULL check
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (8 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 09/21] char: remove chardevs list Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 11/21] char-socket: introduce update_disconnected_filename() Marc-André Lureau
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

g_strdup(NULL) returns NULL already.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 chardev/char.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/chardev/char.c b/chardev/char.c
index aee8b4555d..33dbab6981 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -764,7 +764,7 @@ void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend)
     const char *logfile = qemu_opt_get(opts, "logfile");
 
     backend->has_logfile = logfile != NULL;
-    backend->logfile = logfile ? g_strdup(logfile) : NULL;
+    backend->logfile = g_strdup(logfile);
 
     backend->has_logappend = true;
     backend->logappend = qemu_opt_get_bool(opts, "logappend", false);
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 11/21] char-socket: introduce update_disconnected_filename()
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (9 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 10/21] char: useless NULL check Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-04-11  2:56   ` Philippe Mathieu-Daudé
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 12/21] char-socket: update local address after listen Marc-André Lureau
                   ` (10 subsequent siblings)
  21 siblings, 1 reply; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

This helper will be used in yet another place in the following patch.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 chardev/char-socket.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index dc3d3532a7..e3b5288af7 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -363,6 +363,15 @@ static char *SocketAddress_to_str(const char *prefix, SocketAddress *addr,
     }
 }
 
+static void update_disconnected_filename(SocketChardev *s)
+{
+    Chardev *chr = CHARDEV(s);
+
+    g_free(chr->filename);
+    chr->filename = SocketAddress_to_str("disconnected:", s->addr,
+                                         s->is_listen, s->is_telnet);
+}
+
 static void tcp_chr_disconnect(Chardev *chr)
 {
     SocketChardev *s = SOCKET_CHARDEV(chr);
@@ -377,8 +386,7 @@ static void tcp_chr_disconnect(Chardev *chr)
         s->listen_tag = qio_channel_add_watch(
             QIO_CHANNEL(s->listen_ioc), G_IO_IN, tcp_chr_accept, chr, NULL);
     }
-    chr->filename = SocketAddress_to_str("disconnected:", s->addr,
-                                         s->is_listen, s->is_telnet);
+    update_disconnected_filename(s);
     qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
     if (s->reconnect_time) {
         qemu_chr_socket_restart_timer(chr);
@@ -872,8 +880,7 @@ static void qmp_chardev_open_socket(Chardev *chr,
     /* be isn't opened until we get a connection */
     *be_opened = false;
 
-    chr->filename = SocketAddress_to_str("disconnected:",
-                                         addr, is_listen, is_telnet);
+    update_disconnected_filename(s);
 
     if (is_listen) {
         if (is_telnet) {
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 12/21] char-socket: update local address after listen
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (10 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 11/21] char-socket: introduce update_disconnected_filename() Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 13/21] char-socket: add 'addr' property Marc-André Lureau
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

This is mainly useful to know the actual bound port when using port 0.

For example, when starting qemu with socket on port 0, before:
QEMU waiting for connection on: disconnected:tcp:localhost:0,server
After:
QEMU waiting for connection on: disconnected:tcp:localhost:32454,server

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 chardev/char-socket.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index e3b5288af7..4325a05387 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -908,6 +908,11 @@ static void qmp_chardev_open_socket(Chardev *chr,
             if (qio_channel_socket_listen_sync(sioc, s->addr, errp) < 0) {
                 goto error;
             }
+
+            qapi_free_SocketAddress(s->addr);
+            s->addr = socket_local_address(sioc->fd, errp);
+            update_disconnected_filename(s);
+
             s->listen_ioc = sioc;
             if (is_waitconnect &&
                 qemu_chr_wait_connected(chr, errp) < 0) {
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 13/21] char-socket: add 'addr' property
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (11 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 12/21] char-socket: update local address after listen Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-04-11  2:57   ` Philippe Mathieu-Daudé
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 14/21] char-socket: add 'connected' property Marc-André Lureau
                   ` (8 subsequent siblings)
  21 siblings, 1 reply; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

Add a property to lookup the connection details.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 chardev/char-socket.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 4325a05387..81021c5863 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -1006,6 +1006,15 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
     sock->addr = addr;
 }
 
+static void
+char_socket_get_addr(Object *obj, Visitor *v, const char *name,
+                     void *opaque, Error **errp)
+{
+    SocketChardev *s = SOCKET_CHARDEV(obj);
+
+    visit_type_SocketAddress(v, name, &s->addr, errp);
+}
+
 static void char_socket_class_init(ObjectClass *oc, void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
@@ -1021,6 +1030,10 @@ static void char_socket_class_init(ObjectClass *oc, void *data)
     cc->chr_add_client = tcp_chr_add_client;
     cc->chr_add_watch = tcp_chr_add_watch;
     cc->chr_update_read_handler = tcp_chr_update_read_handler;
+
+    object_class_property_add(oc, "addr", "SocketAddress",
+                              char_socket_get_addr, NULL,
+                              NULL, NULL, &error_abort);
 }
 
 static const TypeInfo char_socket_type_info = {
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 14/21] char-socket: add 'connected' property
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (12 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 13/21] char-socket: add 'addr' property Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-04-11  2:58   ` Philippe Mathieu-Daudé
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 15/21] char-udp: flush as much buffer as possible Marc-André Lureau
                   ` (7 subsequent siblings)
  21 siblings, 1 reply; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 chardev/char-socket.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 81021c5863..06389393fa 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -1015,6 +1015,14 @@ char_socket_get_addr(Object *obj, Visitor *v, const char *name,
     visit_type_SocketAddress(v, name, &s->addr, errp);
 }
 
+static bool
+char_socket_get_connected(Object *obj, Error **errp)
+{
+    SocketChardev *s = SOCKET_CHARDEV(obj);
+
+    return s->connected;
+}
+
 static void char_socket_class_init(ObjectClass *oc, void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
@@ -1034,6 +1042,9 @@ static void char_socket_class_init(ObjectClass *oc, void *data)
     object_class_property_add(oc, "addr", "SocketAddress",
                               char_socket_get_addr, NULL,
                               NULL, NULL, &error_abort);
+
+    object_class_property_add_bool(oc, "connected", char_socket_get_connected,
+                                   NULL, &error_abort);
 }
 
 static const TypeInfo char_socket_type_info = {
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 15/21] char-udp: flush as much buffer as possible
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (13 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 14/21] char-socket: add 'connected' property Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 16/21] tests: add alias check in /char/ringbuf Marc-André Lureau
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

Instead of flushing the buffer byte by byte, call qemu_chr_be_write()
with as much byte possible accepted by the front-end.

Factor out buffer flushing in a common function udp_chr_flush_buffer().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 chardev/char-udp.c | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/chardev/char-udp.c b/chardev/char-udp.c
index 804bd22efa..1958c36de4 100644
--- a/chardev/char-udp.c
+++ b/chardev/char-udp.c
@@ -51,6 +51,18 @@ static int udp_chr_write(Chardev *chr, const uint8_t *buf, int len)
         s->ioc, (const char *)buf, len, NULL);
 }
 
+static void udp_chr_flush_buffer(UdpChardev *s)
+{
+    Chardev *chr = CHARDEV(s);
+
+    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
+        int n = MIN(s->max_size, s->bufcnt - s->bufptr);
+        qemu_chr_be_write(chr, &s->buf[s->bufptr], n);
+        s->bufptr += n;
+        s->max_size = qemu_chr_be_can_write(chr);
+    }
+}
+
 static int udp_chr_read_poll(void *opaque)
 {
     Chardev *chr = CHARDEV(opaque);
@@ -61,11 +73,8 @@ static int udp_chr_read_poll(void *opaque)
     /* If there were any stray characters in the queue process them
      * first
      */
-    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
-        qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
-        s->bufptr++;
-        s->max_size = qemu_chr_be_can_write(chr);
-    }
+    udp_chr_flush_buffer(s);
+
     return s->max_size;
 }
 
@@ -85,13 +94,8 @@ static gboolean udp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
         return FALSE;
     }
     s->bufcnt = ret;
-
     s->bufptr = 0;
-    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
-        qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
-        s->bufptr++;
-        s->max_size = qemu_chr_be_can_write(chr);
-    }
+    udp_chr_flush_buffer(s);
 
     return TRUE;
 }
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 16/21] tests: add alias check in /char/ringbuf
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (14 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 15/21] char-udp: flush as much buffer as possible Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 17/21] tests: add /char/pipe test Marc-André Lureau
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/test-char.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/tests/test-char.c b/tests/test-char.c
index 71de4b35ee..2811644bcd 100644
--- a/tests/test-char.c
+++ b/tests/test-char.c
@@ -104,6 +104,16 @@ static void char_ringbuf_test(void)
 
     qemu_chr_fe_deinit(&be);
     object_unparent(OBJECT(chr));
+
+    /* check alias */
+    opts = qemu_opts_create(qemu_find_opts("chardev"), "memory-label",
+                            1, &error_abort);
+    qemu_opt_set(opts, "backend", "memory", &error_abort);
+    qemu_opt_set(opts, "size", "2", &error_abort);
+    chr = qemu_chr_new_from_opts(opts, NULL);
+    g_assert_nonnull(chr);
+    object_unparent(OBJECT(chr));
+    qemu_opts_del(opts);
 }
 
 static void char_mux_test(void)
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 17/21] tests: add /char/pipe test
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (15 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 16/21] tests: add alias check in /char/ringbuf Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 18/21] tests: add /char/file test Marc-André Lureau
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/test-char.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)

diff --git a/tests/test-char.c b/tests/test-char.c
index 2811644bcd..2b155ffcb7 100644
--- a/tests/test-char.c
+++ b/tests/test-char.c
@@ -1,4 +1,5 @@
 #include "qemu/osdep.h"
+#include <glib/gstdio.h>
 
 #include "qemu-common.h"
 #include "qemu/config-file.h"
@@ -7,12 +8,28 @@
 #include "qapi/error.h"
 #include "qmp-commands.h"
 
+static bool quit;
+
 typedef struct FeHandler {
     int read_count;
     int last_event;
     char read_buf[128];
 } FeHandler;
 
+#ifndef _WIN32
+static void main_loop(void)
+{
+    bool nonblocking;
+    int last_io = 0;
+
+    quit = false;
+    do {
+        nonblocking = last_io > 0;
+        last_io = main_loop_wait(nonblocking);
+    } while (!quit);
+}
+#endif
+
 static int fe_can_read(void *opaque)
 {
     FeHandler *h = opaque;
@@ -28,6 +45,7 @@ static void fe_read(void *opaque, const uint8_t *buf, int size)
 
     memcpy(h->read_buf + h->read_count, buf, size);
     h->read_count += size;
+    quit = true;
 }
 
 static void fe_event(void *opaque, int event)
@@ -35,6 +53,7 @@ static void fe_event(void *opaque, int event)
     FeHandler *h = opaque;
 
     h->last_event = event;
+    quit = true;
 }
 
 #ifdef CONFIG_HAS_GLIB_SUBPROCESS_TESTS
@@ -192,6 +211,72 @@ static void char_mux_test(void)
     object_unparent(OBJECT(chr));
 }
 
+#ifndef _WIN32
+static void char_pipe_test(void)
+{
+    gchar *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL);
+    gchar *tmp, *in, *out, *pipe = g_build_filename(tmp_path, "pipe", NULL);
+    Chardev *chr;
+    CharBackend be;
+    int ret, fd;
+    char buf[10];
+    FeHandler fe = { 0, };
+
+    in = g_strdup_printf("%s.in", pipe);
+    if (mkfifo(in, 0600) < 0) {
+        abort();
+    }
+    out = g_strdup_printf("%s.out", pipe);
+    if (mkfifo(out, 0600) < 0) {
+        abort();
+    }
+
+    tmp = g_strdup_printf("pipe:%s", pipe);
+    chr = qemu_chr_new("pipe", tmp);
+    g_assert_nonnull(chr);
+    g_free(tmp);
+
+    qemu_chr_fe_init(&be, chr, &error_abort);
+
+    ret = qemu_chr_fe_write(&be, (void *)"pipe-out", 9);
+    g_assert_cmpint(ret, ==, 9);
+
+    fd = open(out, O_RDWR);
+    ret = read(fd, buf, sizeof(buf));
+    g_assert_cmpint(ret, ==, 9);
+    g_assert_cmpstr(buf, ==, "pipe-out");
+    close(fd);
+
+    fd = open(in, O_WRONLY);
+    ret = write(fd, "pipe-in", 8);
+    g_assert_cmpint(ret, ==, 8);
+    close(fd);
+
+    qemu_chr_fe_set_handlers(&be,
+                             fe_can_read,
+                             fe_read,
+                             fe_event,
+                             &fe,
+                             NULL, true);
+
+    main_loop();
+
+    g_assert_cmpint(fe.read_count, ==, 8);
+    g_assert_cmpstr(fe.read_buf, ==, "pipe-in");
+
+    qemu_chr_fe_deinit(&be);
+    object_unparent(OBJECT(chr));
+
+    g_assert(g_unlink(in) == 0);
+    g_assert(g_unlink(out) == 0);
+    g_assert(g_rmdir(tmp_path) == 0);
+    g_free(in);
+    g_free(out);
+    g_free(tmp_path);
+    g_free(pipe);
+}
+#endif
+
 static void char_null_test(void)
 {
     Error *err = NULL;
@@ -245,6 +330,8 @@ static void char_invalid_test(void)
 
 int main(int argc, char **argv)
 {
+    qemu_init_main_loop(&error_abort);
+
     g_test_init(&argc, &argv, NULL);
 
     module_call_init(MODULE_INIT_QOM);
@@ -258,6 +345,9 @@ int main(int argc, char **argv)
     g_test_add_func("/char/stdio/subprocess", char_stdio_test_subprocess);
     g_test_add_func("/char/stdio", char_stdio_test);
 #endif
+#ifndef _WIN32
+    g_test_add_func("/char/pipe", char_pipe_test);
+#endif
 
     return g_test_run();
 }
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 18/21] tests: add /char/file test
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (16 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 17/21] tests: add /char/pipe test Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 19/21] tests: add /char/socket test Marc-André Lureau
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/test-char.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/tests/test-char.c b/tests/test-char.c
index 2b155ffcb7..87a4e2986d 100644
--- a/tests/test-char.c
+++ b/tests/test-char.c
@@ -277,6 +277,76 @@ static void char_pipe_test(void)
 }
 #endif
 
+static void char_file_test(void)
+{
+    char *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL);
+    char *out = g_build_filename(tmp_path, "out", NULL);
+    char *contents = NULL;
+    ChardevFile file = { .out = out };
+    ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE,
+                               .u.file.data = &file };
+    Chardev *chr;
+    gsize length;
+    int ret;
+
+    chr = qemu_chardev_new(NULL, TYPE_CHARDEV_FILE, &backend,
+                           &error_abort);
+    ret = qemu_chr_write_all(chr, (uint8_t *)"hello!", 6);
+    g_assert_cmpint(ret, ==, 6);
+    object_unref(OBJECT(chr));
+
+    ret = g_file_get_contents(out, &contents, &length, NULL);
+    g_assert(ret == TRUE);
+    g_assert_cmpint(length, ==, 6);
+    g_assert(strncmp(contents, "hello!", 6) == 0);
+    g_free(contents);
+
+#ifndef _WIN32
+    {
+        CharBackend be;
+        FeHandler fe = { 0, };
+        char *fifo = g_build_filename(tmp_path, "fifo", NULL);
+        int fd;
+
+        if (mkfifo(fifo, 0600) < 0) {
+            abort();
+        }
+
+        fd = open(fifo, O_RDWR);
+        ret = write(fd, "fifo-in", 8);
+        g_assert_cmpint(ret, ==, 8);
+
+        file.in = fifo;
+        file.has_in = true;
+        chr = qemu_chardev_new(NULL, TYPE_CHARDEV_FILE, &backend,
+                               &error_abort);
+
+        qemu_chr_fe_init(&be, chr, &error_abort);
+        qemu_chr_fe_set_handlers(&be,
+                                 fe_can_read,
+                                 fe_read,
+                                 fe_event,
+                                 &fe, NULL, true);
+
+        main_loop();
+
+        close(fd);
+
+        g_assert_cmpint(fe.read_count, ==, 8);
+        g_assert_cmpstr(fe.read_buf, ==, "fifo-in");
+        qemu_chr_fe_deinit(&be);
+        object_unref(OBJECT(chr));
+        g_unlink(fifo);
+        g_free(fifo);
+    }
+#endif
+
+    g_unlink(out);
+    g_rmdir(tmp_path);
+    g_free(tmp_path);
+    g_free(out);
+}
+
 static void char_null_test(void)
 {
     Error *err = NULL;
@@ -348,6 +418,7 @@ int main(int argc, char **argv)
 #ifndef _WIN32
     g_test_add_func("/char/pipe", char_pipe_test);
 #endif
+    g_test_add_func("/char/file", char_file_test);
 
     return g_test_run();
 }
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 19/21] tests: add /char/socket test
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (17 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 18/21] tests: add /char/file test Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 20/21] tests: add /char/udp test Marc-André Lureau
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/test-char.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 112 insertions(+), 2 deletions(-)

diff --git a/tests/test-char.c b/tests/test-char.c
index 87a4e2986d..9971498391 100644
--- a/tests/test-char.c
+++ b/tests/test-char.c
@@ -3,9 +3,11 @@
 
 #include "qemu-common.h"
 #include "qemu/config-file.h"
+#include "qemu/sockets.h"
 #include "sysemu/char.h"
 #include "sysemu/sysemu.h"
 #include "qapi/error.h"
+#include "qom/qom-qobject.h"
 #include "qmp-commands.h"
 
 static bool quit;
@@ -16,7 +18,6 @@ typedef struct FeHandler {
     char read_buf[128];
 } FeHandler;
 
-#ifndef _WIN32
 static void main_loop(void)
 {
     bool nonblocking;
@@ -28,7 +29,6 @@ static void main_loop(void)
         last_io = main_loop_wait(nonblocking);
     } while (!quit);
 }
-#endif
 
 static int fe_can_read(void *opaque)
 {
@@ -211,6 +211,114 @@ static void char_mux_test(void)
     object_unparent(OBJECT(chr));
 }
 
+typedef struct SocketIdleData {
+    GMainLoop *loop;
+    Chardev *chr;
+    bool conn_expected;
+    CharBackend *be;
+    CharBackend *client_be;
+} SocketIdleData;
+
+static gboolean char_socket_test_idle(gpointer user_data)
+{
+    SocketIdleData *data = user_data;
+
+    if (object_property_get_bool(OBJECT(data->chr), "connected", NULL)
+        == data->conn_expected) {
+        quit = true;
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static void socket_read(void *opaque, const uint8_t *buf, int size)
+{
+    SocketIdleData *data = opaque;
+
+    g_assert_cmpint(size, ==, 1);
+    g_assert_cmpint(*buf, ==, 'Z');
+
+    size = qemu_chr_fe_write(data->be, (const uint8_t *)"hello", 5);
+    g_assert_cmpint(size, ==, 5);
+}
+
+static int socket_can_read(void *opaque)
+{
+    return 10;
+}
+
+static void socket_read_hello(void *opaque, const uint8_t *buf, int size)
+{
+    g_assert_cmpint(size, ==, 5);
+    g_assert(strncmp((char *)buf, "hello", 5) == 0);
+
+    quit = true;
+}
+
+static int socket_can_read_hello(void *opaque)
+{
+    return 10;
+}
+
+static void char_socket_test(void)
+{
+    Chardev *chr = qemu_chr_new("server", "tcp:127.0.0.1:0,server,nowait");
+    Chardev *chr_client;
+    QObject *addr;
+    QDict *qdict, *data;
+    const char *port;
+    SocketIdleData d = { .chr = chr };
+    CharBackend be;
+    CharBackend client_be;
+    char *tmp;
+
+    d.be = &be;
+    d.client_be = &be;
+
+    g_assert_nonnull(chr);
+    g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_abort));
+
+    addr = object_property_get_qobject(OBJECT(chr), "addr", &error_abort);
+    qdict = qobject_to_qdict(addr);
+    data = qdict_get_qdict(qdict, "data");
+    port = qdict_get_str(data, "port");
+    tmp = g_strdup_printf("tcp:127.0.0.1:%s", port);
+    QDECREF(qdict);
+
+    qemu_chr_fe_init(&be, chr, &error_abort);
+    qemu_chr_fe_set_handlers(&be, socket_can_read, socket_read,
+                             NULL, &d, NULL, true);
+
+    chr_client = qemu_chr_new("client", tmp);
+    qemu_chr_fe_init(&client_be, chr_client, &error_abort);
+    qemu_chr_fe_set_handlers(&client_be, socket_can_read_hello,
+                             socket_read_hello,
+                             NULL, &d, NULL, true);
+    g_free(tmp);
+
+    d.conn_expected = true;
+    guint id = g_idle_add(char_socket_test_idle, &d);
+    g_source_set_name_by_id(id, "test-idle");
+    g_assert_cmpint(id, >, 0);
+    main_loop();
+
+    g_assert(object_property_get_bool(OBJECT(chr), "connected", &error_abort));
+    g_assert(object_property_get_bool(OBJECT(chr_client),
+                                      "connected", &error_abort));
+
+    qemu_chr_write_all(chr_client, (const uint8_t *)"Z", 1);
+    main_loop();
+
+    object_unparent(OBJECT(chr_client));
+
+    d.conn_expected = false;
+    g_idle_add(char_socket_test_idle, &d);
+    main_loop();
+
+    object_unparent(OBJECT(chr));
+}
+
 #ifndef _WIN32
 static void char_pipe_test(void)
 {
@@ -401,6 +509,7 @@ static void char_invalid_test(void)
 int main(int argc, char **argv)
 {
     qemu_init_main_loop(&error_abort);
+    socket_init();
 
     g_test_init(&argc, &argv, NULL);
 
@@ -419,6 +528,7 @@ int main(int argc, char **argv)
     g_test_add_func("/char/pipe", char_pipe_test);
 #endif
     g_test_add_func("/char/file", char_file_test);
+    g_test_add_func("/char/socket", char_socket_test);
 
     return g_test_run();
 }
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 20/21] tests: add /char/udp test
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (18 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 19/21] tests: add /char/socket test Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 21/21] tests: add /char/console test Marc-André Lureau
  2017-04-10 13:58 ` [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
  21 siblings, 0 replies; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/test-char.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/tests/test-char.c b/tests/test-char.c
index 9971498391..19707bfcda 100644
--- a/tests/test-char.c
+++ b/tests/test-char.c
@@ -385,6 +385,51 @@ static void char_pipe_test(void)
 }
 #endif
 
+static void char_udp_test(void)
+{
+    struct sockaddr_in addr = { 0, }, other;
+    SocketIdleData d = { 0, };
+    Chardev *chr;
+    CharBackend be;
+    socklen_t alen = sizeof(addr);
+    int ret, sock = qemu_socket(PF_INET, SOCK_DGRAM, 0);
+    char buf[10];
+    char *tmp;
+
+    g_assert_cmpint(sock, >, 0);
+    addr.sin_family = AF_INET ;
+    addr.sin_addr.s_addr = htonl(INADDR_ANY);
+    addr.sin_port = 0;
+    ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
+    g_assert_cmpint(ret, ==, 0);
+    ret = getsockname(sock, (struct sockaddr *)&addr, &alen);
+    g_assert_cmpint(ret, ==, 0);
+
+    tmp = g_strdup_printf("udp:127.0.0.1:%d",
+                          ntohs(addr.sin_port));
+    chr = qemu_chr_new("client", tmp);
+    g_assert_nonnull(chr);
+
+    d.chr = chr;
+    qemu_chr_fe_init(&be, chr, &error_abort);
+    qemu_chr_fe_set_handlers(&be, socket_can_read_hello, socket_read_hello,
+                             NULL, &d, NULL, true);
+    ret = qemu_chr_write_all(chr, (uint8_t *)"hello", 5);
+    g_assert_cmpint(ret, ==, 5);
+
+    alen = sizeof(addr);
+    ret = recvfrom(sock, buf, sizeof(buf), 0,
+                   (struct sockaddr *)&other, &alen);
+    g_assert_cmpint(ret, ==, 5);
+    ret = sendto(sock, buf, 5, 0, (struct sockaddr *)&other, alen);
+    g_assert_cmpint(ret, ==, 5);
+
+    main_loop();
+
+    close(sock);
+    g_free(tmp);
+}
+
 static void char_file_test(void)
 {
     char *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL);
@@ -529,6 +574,7 @@ int main(int argc, char **argv)
 #endif
     g_test_add_func("/char/file", char_file_test);
     g_test_add_func("/char/socket", char_socket_test);
+    g_test_add_func("/char/udp", char_udp_test);
 
     return g_test_run();
 }
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH v3 21/21] tests: add /char/console test
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (19 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 20/21] tests: add /char/udp test Marc-André Lureau
@ 2017-03-16  9:21 ` Marc-André Lureau
  2017-04-10 13:58 ` [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
  21 siblings, 0 replies; 33+ messages in thread
From: Marc-André Lureau @ 2017-03-16  9:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, eblake, Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/test-char.c | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/tests/test-char.c b/tests/test-char.c
index 19707bfcda..773a1c36ba 100644
--- a/tests/test-char.c
+++ b/tests/test-char.c
@@ -57,6 +57,32 @@ static void fe_event(void *opaque, int event)
 }
 
 #ifdef CONFIG_HAS_GLIB_SUBPROCESS_TESTS
+#ifdef _WIN32
+static void char_console_test_subprocess(void)
+{
+    QemuOpts *opts;
+    Chardev *chr;
+
+    opts = qemu_opts_create(qemu_find_opts("chardev"), "console-label",
+                            1, &error_abort);
+    qemu_opt_set(opts, "backend", "console", &error_abort);
+
+    chr = qemu_chr_new_from_opts(opts, NULL);
+    g_assert_nonnull(chr);
+
+    qemu_chr_write_all(chr, (const uint8_t *)"CONSOLE", 7);
+
+    qemu_opts_del(opts);
+    object_unparent(OBJECT(chr));
+}
+
+static void char_console_test(void)
+{
+    g_test_trap_subprocess("/char/console/subprocess", 0, 0);
+    g_test_trap_assert_passed();
+    g_test_trap_assert_stdout("CONSOLE");
+}
+#endif
 static void char_stdio_test_subprocess(void)
 {
     Chardev *chr;
@@ -83,7 +109,6 @@ static void char_stdio_test(void)
 }
 #endif
 
-
 static void char_ringbuf_test(void)
 {
     QemuOpts *opts;
@@ -566,6 +591,10 @@ int main(int argc, char **argv)
     g_test_add_func("/char/ringbuf", char_ringbuf_test);
     g_test_add_func("/char/mux", char_mux_test);
 #ifdef CONFIG_HAS_GLIB_SUBPROCESS_TESTS
+#ifdef _WIN32
+    g_test_add_func("/char/console/subprocess", char_console_test_subprocess);
+    g_test_add_func("/char/console", char_console_test);
+#endif
     g_test_add_func("/char/stdio/subprocess", char_stdio_test_subprocess);
     g_test_add_func("/char/stdio", char_stdio_test);
 #endif
-- 
2.12.0.191.gc5d8de91d

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v3 01/21] char: remove qemu_chr_be_generic_open
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 01/21] char: remove qemu_chr_be_generic_open Marc-André Lureau
@ 2017-04-04 15:08   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 33+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-04-04 15:08 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel; +Cc: pbonzini

On 03/16/2017 06:21 AM, Marc-André Lureau wrote:
> The function simply alias and hides the real event function.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> Reviewed-by: Eric Blake <eblake@redhat.com>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>  include/sysemu/char.h |  1 -
>  chardev/char-pty.c    |  2 +-
>  chardev/char-socket.c |  2 +-
>  chardev/char.c        | 10 ++--------
>  ui/console.c          |  2 +-
>  ui/gtk.c              |  2 +-
>  6 files changed, 6 insertions(+), 13 deletions(-)
>
> diff --git a/include/sysemu/char.h b/include/sysemu/char.h
> index 450881d42c..a30ff3fa80 100644
> --- a/include/sysemu/char.h
> +++ b/include/sysemu/char.h
> @@ -427,7 +427,6 @@ void qemu_chr_fe_set_handlers(CharBackend *b,
>   */
>  void qemu_chr_fe_take_focus(CharBackend *b);
>
> -void qemu_chr_be_generic_open(Chardev *s);
>  void qemu_chr_fe_accept_input(CharBackend *be);
>  int qemu_chr_add_client(Chardev *s, int fd);
>  Chardev *qemu_chr_find(const char *name);
> diff --git a/chardev/char-pty.c b/chardev/char-pty.c
> index a6337be8aa..aa9d0cb2c3 100644
> --- a/chardev/char-pty.c
> +++ b/chardev/char-pty.c
> @@ -185,7 +185,7 @@ static gboolean qemu_chr_be_generic_open_func(gpointer opaque)
>      PtyChardev *s = PTY_CHARDEV(opaque);
>
>      s->open_tag = 0;
> -    qemu_chr_be_generic_open(chr);
> +    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>      return FALSE;
>  }
>
> diff --git a/chardev/char-socket.c b/chardev/char-socket.c
> index d7e92e1bd3..dc3d3532a7 100644
> --- a/chardev/char-socket.c
> +++ b/chardev/char-socket.c
> @@ -486,7 +486,7 @@ static void tcp_chr_connect(void *opaque)
>                                             tcp_chr_read,
>                                             chr, NULL);
>      }
> -    qemu_chr_be_generic_open(chr);
> +    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>  }
>
>  static void tcp_chr_update_read_handler(Chardev *chr,
> diff --git a/chardev/char.c b/chardev/char.c
> index 3df116350b..aad639b620 100644
> --- a/chardev/char.c
> +++ b/chardev/char.c
> @@ -66,12 +66,6 @@ void qemu_chr_be_event(Chardev *s, int event)
>      be->chr_event(be->opaque, event);
>  }
>
> -void qemu_chr_be_generic_open(Chardev *s)
> -{
> -    qemu_chr_be_event(s, CHR_EVENT_OPENED);
> -}
> -
> -
>  /* Not reporting errors from writing to logfile, as logs are
>   * defined to be "best effort" only */
>  static void qemu_chr_fe_write_log(Chardev *s,
> @@ -469,7 +463,7 @@ static void muxes_realize_done(Notifier *notifier, void *unused)
>              /* mark mux as OPENED so any new FEs will immediately receive
>               * OPENED event
>               */
> -            qemu_chr_be_generic_open(chr);
> +            qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>          }
>      }
>      muxes_realized = true;
> @@ -581,7 +575,7 @@ void qemu_chr_fe_set_handlers(CharBackend *b,
>          /* We're connecting to an already opened device, so let's make sure we
>             also get the open event */
>          if (s->be_open) {
> -            qemu_chr_be_generic_open(s);
> +            qemu_chr_be_event(s, CHR_EVENT_OPENED);
>          }
>      }
>
> diff --git a/ui/console.c b/ui/console.c
> index d1ff7504ec..d88c52efe5 100644
> --- a/ui/console.c
> +++ b/ui/console.c
> @@ -2070,7 +2070,7 @@ static void text_console_do_init(Chardev *chr, DisplayState *ds)
>          s->t_attrib = s->t_attrib_default;
>      }
>
> -    qemu_chr_be_generic_open(chr);
> +    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>  }
>
>  static void vc_chr_open(Chardev *chr,
> diff --git a/ui/gtk.c b/ui/gtk.c
> index a86848f3b0..7479ceef35 100644
> --- a/ui/gtk.c
> +++ b/ui/gtk.c
> @@ -1868,7 +1868,7 @@ static GSList *gd_vc_vte_init(GtkDisplayState *s, VirtualConsole *vc,
>      gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook), vc->tab_item,
>                               gtk_label_new(vc->label));
>
> -    qemu_chr_be_generic_open(vc->vte.chr);
> +    qemu_chr_be_event(vc->vte.chr, CHR_EVENT_OPENED);
>
>      return group;
>  }
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v3 02/21] mux: simplfy muxes_realize_done
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 02/21] mux: simplfy muxes_realize_done Marc-André Lureau
@ 2017-04-04 15:14   ` Philippe Mathieu-Daudé
  2017-04-04 16:31     ` Marc-André Lureau
  0 siblings, 1 reply; 33+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-04-04 15:14 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel; +Cc: pbonzini

Hi Marc-André,

On 03/16/2017 06:21 AM, Marc-André Lureau wrote:
> mux_chr_event() already send events to all backends, rename it,
> export it, and use it from muxes_realize_done. This should help abstract
> away mux implementation.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> Reviewed-by: Eric Blake <eblake@redhat.com>
> ---
>  chardev/char-mux.h |  2 +-
>  chardev/char-mux.c | 11 ++++++++---
>  chardev/char.c     |  9 ++-------
>  3 files changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/chardev/char-mux.h b/chardev/char-mux.h
> index 9a2fffce91..3f41dfcfd2 100644
> --- a/chardev/char-mux.h
> +++ b/chardev/char-mux.h
> @@ -58,6 +58,6 @@ typedef struct MuxChardev {
>
>  void mux_chr_set_handlers(Chardev *chr, GMainContext *context);
>  void mux_set_focus(Chardev *chr, int focus);
> -void mux_chr_send_event(MuxChardev *d, int mux_nr, int event);
> +void mux_chr_send_all_event(Chardev *chr, int event);
>
>  #endif /* CHAR_MUX_H */
> diff --git a/chardev/char-mux.c b/chardev/char-mux.c
> index 5547a36a0a..37d42c65c6 100644
> --- a/chardev/char-mux.c
> +++ b/chardev/char-mux.c
> @@ -114,7 +114,7 @@ static void mux_print_help(Chardev *chr)
>      }
>  }
>
> -void mux_chr_send_event(MuxChardev *d, int mux_nr, int event)
> +static void mux_chr_send_event(MuxChardev *d, int mux_nr, int event)
>  {
>      CharBackend *be = d->backends[mux_nr];
>
> @@ -222,9 +222,9 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
>
>  bool muxes_realized;
>
> -static void mux_chr_event(void *opaque, int event)
> +void mux_chr_send_all_event(Chardev *chr, int event)
>  {
> -    MuxChardev *d = MUX_CHARDEV(opaque);
> +    MuxChardev *d = MUX_CHARDEV(chr);
>      int i;
>
>      if (!muxes_realized) {
> @@ -237,6 +237,11 @@ static void mux_chr_event(void *opaque, int event)
>      }
>  }
>
> +static void mux_chr_event(void *opaque, int event)

Why use an opaque pointer and not Chardev *chr here? Not a big deal but 
it eases debugging sessions.
Anyway it'll be correctly displayed single-stepping in :)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> +{
> +    mux_chr_send_all_event(CHARDEV(opaque), event);
> +}
> +
>  static GSource *mux_chr_add_watch(Chardev *s, GIOCondition cond)
>  {
>      MuxChardev *d = MUX_CHARDEV(s);
> diff --git a/chardev/char.c b/chardev/char.c
> index aad639b620..674c097fbe 100644
> --- a/chardev/char.c
> +++ b/chardev/char.c
> @@ -451,22 +451,17 @@ static void muxes_realize_done(Notifier *notifier, void *unused)
>  {
>      Chardev *chr;
>
> +    muxes_realized = true;
>      QTAILQ_FOREACH(chr, &chardevs, next) {
>          if (CHARDEV_IS_MUX(chr)) {
> -            MuxChardev *d = MUX_CHARDEV(chr);
> -            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);
> -            }
> +            mux_chr_send_all_event(CHARDEV(chr), CHR_EVENT_OPENED);
>              /* mark mux as OPENED so any new FEs will immediately receive
>               * OPENED event
>               */
>              qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>          }
>      }
> -    muxes_realized = true;
>  }
>
>  static Notifier muxes_realize_notify = {
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v3 03/21] xen: use a better chardev type check
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 03/21] xen: use a better chardev type check Marc-André Lureau
@ 2017-04-04 15:15   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 33+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-04-04 15:15 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel; +Cc: pbonzini

On 03/16/2017 06:21 AM, Marc-André Lureau wrote:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> Reviewed-by: Eric Blake <eblake@redhat.com>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>  xen-common.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/xen-common.c b/xen-common.c
> index fd2c92847e..d46685ef4e 100644
> --- a/xen-common.c
> +++ b/xen-common.c
> @@ -34,7 +34,7 @@ static int store_dev_info(int domid, Chardev *cs, const char *string)
>      int ret = -1;
>
>      /* Only continue if we're talking to a pty. */
> -    if (strncmp(cs->filename, "pty:", 4)) {
> +    if (!CHARDEV_IS_PTY(cs)) {
>          return 0;
>      }
>      pts = cs->filename + 4;
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v3 02/21] mux: simplfy muxes_realize_done
  2017-04-04 15:14   ` Philippe Mathieu-Daudé
@ 2017-04-04 16:31     ` Marc-André Lureau
  2017-04-11  3:02       ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 33+ messages in thread
From: Marc-André Lureau @ 2017-04-04 16:31 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé; +Cc: qemu-devel, pbonzini

Hi Philippe

----- Original Message -----
> Hi Marc-André,
> 
> On 03/16/2017 06:21 AM, Marc-André Lureau wrote:
> > mux_chr_event() already send events to all backends, rename it,
> > export it, and use it from muxes_realize_done. This should help abstract
> > away mux implementation.
> >
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > Reviewed-by: Eric Blake <eblake@redhat.com>
> > ---
> >  chardev/char-mux.h |  2 +-
> >  chardev/char-mux.c | 11 ++++++++---
> >  chardev/char.c     |  9 ++-------
> >  3 files changed, 11 insertions(+), 11 deletions(-)
> >
> > diff --git a/chardev/char-mux.h b/chardev/char-mux.h
> > index 9a2fffce91..3f41dfcfd2 100644
> > --- a/chardev/char-mux.h
> > +++ b/chardev/char-mux.h
> > @@ -58,6 +58,6 @@ typedef struct MuxChardev {
> >
> >  void mux_chr_set_handlers(Chardev *chr, GMainContext *context);
> >  void mux_set_focus(Chardev *chr, int focus);
> > -void mux_chr_send_event(MuxChardev *d, int mux_nr, int event);
> > +void mux_chr_send_all_event(Chardev *chr, int event);
> >
> >  #endif /* CHAR_MUX_H */
> > diff --git a/chardev/char-mux.c b/chardev/char-mux.c
> > index 5547a36a0a..37d42c65c6 100644
> > --- a/chardev/char-mux.c
> > +++ b/chardev/char-mux.c
> > @@ -114,7 +114,7 @@ static void mux_print_help(Chardev *chr)
> >      }
> >  }
> >
> > -void mux_chr_send_event(MuxChardev *d, int mux_nr, int event)
> > +static void mux_chr_send_event(MuxChardev *d, int mux_nr, int event)
> >  {
> >      CharBackend *be = d->backends[mux_nr];
> >
> > @@ -222,9 +222,9 @@ static void mux_chr_read(void *opaque, const uint8_t
> > *buf, int size)
> >
> >  bool muxes_realized;
> >
> > -static void mux_chr_event(void *opaque, int event)
> > +void mux_chr_send_all_event(Chardev *chr, int event)
> >  {
> > -    MuxChardev *d = MUX_CHARDEV(opaque);
> > +    MuxChardev *d = MUX_CHARDEV(chr);
> >      int i;
> >
> >      if (!muxes_realized) {
> > @@ -237,6 +237,11 @@ static void mux_chr_event(void *opaque, int event)
> >      }
> >  }
> >
> > +static void mux_chr_event(void *opaque, int event)
> 
> Why use an opaque pointer and not Chardev *chr here? Not a big deal but
> it eases debugging sessions.
> Anyway it'll be correctly displayed single-stepping in :)

It's the signature of IOEventHandler, avoiding casting.

> 
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> 
> > +{
> > +    mux_chr_send_all_event(CHARDEV(opaque), event);
> > +}
> > +
> >  static GSource *mux_chr_add_watch(Chardev *s, GIOCondition cond)
> >  {
> >      MuxChardev *d = MUX_CHARDEV(s);
> > diff --git a/chardev/char.c b/chardev/char.c
> > index aad639b620..674c097fbe 100644
> > --- a/chardev/char.c
> > +++ b/chardev/char.c
> > @@ -451,22 +451,17 @@ static void muxes_realize_done(Notifier *notifier,
> > void *unused)
> >  {
> >      Chardev *chr;
> >
> > +    muxes_realized = true;
> >      QTAILQ_FOREACH(chr, &chardevs, next) {
> >          if (CHARDEV_IS_MUX(chr)) {
> > -            MuxChardev *d = MUX_CHARDEV(chr);
> > -            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);
> > -            }
> > +            mux_chr_send_all_event(CHARDEV(chr), CHR_EVENT_OPENED);
> >              /* mark mux as OPENED so any new FEs will immediately receive
> >               * OPENED event
> >               */
> >              qemu_chr_be_event(chr, CHR_EVENT_OPENED);
> >          }
> >      }
> > -    muxes_realized = true;
> >  }
> >
> >  static Notifier muxes_realize_notify = {
> >
> 

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9)
  2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
                   ` (20 preceding siblings ...)
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 21/21] tests: add /char/console test Marc-André Lureau
@ 2017-04-10 13:58 ` Marc-André Lureau
  2017-04-18  9:50   ` Marc-André Lureau
  21 siblings, 1 reply; 33+ messages in thread
From: Marc-André Lureau @ 2017-04-10 13:58 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Eric Blake, Philippe Mathieu-Daudé

On Thu, Mar 16, 2017 at 10:23 AM Marc-André Lureau <
marcandre.lureau@redhat.com> wrote:

> Hi,
>
> The following series contains various patches:
> - replace "chardevs" list for a /chardevs container object
> - add a few read-only socket properties mainly useful for testing
> - some chardev related clean-ups
> - add various chardev tests
>
> This series is part of a larger refactoring series that I try to keep
> up to date here: https://github.com/elmarco/qemu/commits/chrfe
>
>
ping (most of the patches are still unreviewed)
thanks


> v3:
> - open code object_new_with_props() as suggest by Paolo
> - added some r-b tags
> - rebased
>
> v2:
> - replaced root container unref with a TODO
> - call object_unparent() directly instead of qemu_chr_delete()
> - remove bad qcow2 NULL check removal
> - rebased
>
> Marc-André Lureau (21):
>   char: remove qemu_chr_be_generic_open
>   mux: simplfy muxes_realize_done
>   xen: use a better chardev type check
>   container: don't leak container reference
>   char: add a /chardevs container
>   vl: add todo note about root container cleanup
>   char: use /chardevs container instead of chardevs list
>   char: remove qemu_chardev_add
>   char: remove chardevs list
>   char: useless NULL check
>   char-socket: introduce update_disconnected_filename()
>   char-socket: update local address after listen
>   char-socket: add 'addr' property
>   char-socket: add 'connected' property
>   char-udp: flush as much buffer as possible
>   tests: add alias check in /char/ringbuf
>   tests: add /char/pipe test
>   tests: add /char/file test
>   tests: add /char/socket test
>   tests: add /char/udp test
>   tests: add /char/console test
>
>  chardev/char-mux.h          |   2 +-
>  include/sysemu/char.h       |  10 --
>  chardev/char-mux.c          |  11 +-
>  chardev/char-pty.c          |   2 +-
>  chardev/char-socket.c       |  46 +++++-
>  chardev/char-udp.c          |  26 ++--
>  chardev/char.c              | 148 ++++++++----------
>  gdbstub.c                   |   4 +-
>  hw/usb/ccid-card-passthru.c |   2 +-
>  hw/usb/redirect.c           |   2 +-
>  net/vhost-user.c            |   2 +-
>  qom/container.c             |   1 +
>  tests/test-char.c           | 366
> +++++++++++++++++++++++++++++++++++++++++++-
>  tests/vhost-user-test.c     |   2 +-
>  ui/console.c                |   2 +-
>  ui/gtk.c                    |   2 +-
>  vl.c                        |   1 +
>  xen-common.c                |   2 +-
>  18 files changed, 504 insertions(+), 127 deletions(-)
>
> --
> 2.12.0.191.gc5d8de91d
>
>
> --
Marc-André Lureau

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v3 04/21] container: don't leak container reference
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 04/21] container: don't leak container reference Marc-André Lureau
@ 2017-04-11  2:53   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 33+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-04-11  2:53 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel; +Cc: pbonzini

On 03/16/2017 06:21 AM, Marc-André Lureau wrote:
> object_property_add_child() references the child, unref it after to
> avoid ref leaks.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>  qom/container.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/qom/container.c b/qom/container.c
> index c9eb49b01e..f6ccaf7ea7 100644
> --- a/qom/container.c
> +++ b/qom/container.c
> @@ -40,6 +40,7 @@ Object *container_get(Object *root, const char *path)
>          if (!child) {
>              child = object_new("container");
>              object_property_add_child(obj, parts[i], child, NULL);
> +            object_unref(child);
>          }
>      }
>
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v3 11/21] char-socket: introduce update_disconnected_filename()
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 11/21] char-socket: introduce update_disconnected_filename() Marc-André Lureau
@ 2017-04-11  2:56   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 33+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-04-11  2:56 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel; +Cc: pbonzini

On 03/16/2017 06:21 AM, Marc-André Lureau wrote:
> This helper will be used in yet another place in the following patch.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>  chardev/char-socket.c | 15 +++++++++++----
>  1 file changed, 11 insertions(+), 4 deletions(-)
>
> diff --git a/chardev/char-socket.c b/chardev/char-socket.c
> index dc3d3532a7..e3b5288af7 100644
> --- a/chardev/char-socket.c
> +++ b/chardev/char-socket.c
> @@ -363,6 +363,15 @@ static char *SocketAddress_to_str(const char *prefix, SocketAddress *addr,
>      }
>  }
>
> +static void update_disconnected_filename(SocketChardev *s)
> +{
> +    Chardev *chr = CHARDEV(s);
> +
> +    g_free(chr->filename);
> +    chr->filename = SocketAddress_to_str("disconnected:", s->addr,
> +                                         s->is_listen, s->is_telnet);
> +}
> +
>  static void tcp_chr_disconnect(Chardev *chr)
>  {
>      SocketChardev *s = SOCKET_CHARDEV(chr);
> @@ -377,8 +386,7 @@ static void tcp_chr_disconnect(Chardev *chr)
>          s->listen_tag = qio_channel_add_watch(
>              QIO_CHANNEL(s->listen_ioc), G_IO_IN, tcp_chr_accept, chr, NULL);
>      }
> -    chr->filename = SocketAddress_to_str("disconnected:", s->addr,
> -                                         s->is_listen, s->is_telnet);
> +    update_disconnected_filename(s);
>      qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
>      if (s->reconnect_time) {
>          qemu_chr_socket_restart_timer(chr);
> @@ -872,8 +880,7 @@ static void qmp_chardev_open_socket(Chardev *chr,
>      /* be isn't opened until we get a connection */
>      *be_opened = false;
>
> -    chr->filename = SocketAddress_to_str("disconnected:",
> -                                         addr, is_listen, is_telnet);
> +    update_disconnected_filename(s);
>
>      if (is_listen) {
>          if (is_telnet) {
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v3 13/21] char-socket: add 'addr' property
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 13/21] char-socket: add 'addr' property Marc-André Lureau
@ 2017-04-11  2:57   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 33+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-04-11  2:57 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel; +Cc: pbonzini

On 03/16/2017 06:21 AM, Marc-André Lureau wrote:
> Add a property to lookup the connection details.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>  chardev/char-socket.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
>
> diff --git a/chardev/char-socket.c b/chardev/char-socket.c
> index 4325a05387..81021c5863 100644
> --- a/chardev/char-socket.c
> +++ b/chardev/char-socket.c
> @@ -1006,6 +1006,15 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
>      sock->addr = addr;
>  }
>
> +static void
> +char_socket_get_addr(Object *obj, Visitor *v, const char *name,
> +                     void *opaque, Error **errp)
> +{
> +    SocketChardev *s = SOCKET_CHARDEV(obj);
> +
> +    visit_type_SocketAddress(v, name, &s->addr, errp);
> +}
> +
>  static void char_socket_class_init(ObjectClass *oc, void *data)
>  {
>      ChardevClass *cc = CHARDEV_CLASS(oc);
> @@ -1021,6 +1030,10 @@ static void char_socket_class_init(ObjectClass *oc, void *data)
>      cc->chr_add_client = tcp_chr_add_client;
>      cc->chr_add_watch = tcp_chr_add_watch;
>      cc->chr_update_read_handler = tcp_chr_update_read_handler;
> +
> +    object_class_property_add(oc, "addr", "SocketAddress",
> +                              char_socket_get_addr, NULL,
> +                              NULL, NULL, &error_abort);
>  }
>
>  static const TypeInfo char_socket_type_info = {
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v3 14/21] char-socket: add 'connected' property
  2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 14/21] char-socket: add 'connected' property Marc-André Lureau
@ 2017-04-11  2:58   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 33+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-04-11  2:58 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel; +Cc: pbonzini

On 03/16/2017 06:21 AM, Marc-André Lureau wrote:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>  chardev/char-socket.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>
> diff --git a/chardev/char-socket.c b/chardev/char-socket.c
> index 81021c5863..06389393fa 100644
> --- a/chardev/char-socket.c
> +++ b/chardev/char-socket.c
> @@ -1015,6 +1015,14 @@ char_socket_get_addr(Object *obj, Visitor *v, const char *name,
>      visit_type_SocketAddress(v, name, &s->addr, errp);
>  }
>
> +static bool
> +char_socket_get_connected(Object *obj, Error **errp)
> +{
> +    SocketChardev *s = SOCKET_CHARDEV(obj);
> +
> +    return s->connected;
> +}
> +
>  static void char_socket_class_init(ObjectClass *oc, void *data)
>  {
>      ChardevClass *cc = CHARDEV_CLASS(oc);
> @@ -1034,6 +1042,9 @@ static void char_socket_class_init(ObjectClass *oc, void *data)
>      object_class_property_add(oc, "addr", "SocketAddress",
>                                char_socket_get_addr, NULL,
>                                NULL, NULL, &error_abort);
> +
> +    object_class_property_add_bool(oc, "connected", char_socket_get_connected,
> +                                   NULL, &error_abort);
>  }
>
>  static const TypeInfo char_socket_type_info = {
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v3 02/21] mux: simplfy muxes_realize_done
  2017-04-04 16:31     ` Marc-André Lureau
@ 2017-04-11  3:02       ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 33+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-04-11  3:02 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: pbonzini, qemu-devel

On 04/04/2017 01:31 PM, Marc-André Lureau wrote:
> Hi Philippe
>
> ----- Original Message -----
>> Hi Marc-André,
>>
>> On 03/16/2017 06:21 AM, Marc-André Lureau wrote:
>>> mux_chr_event() already send events to all backends, rename it,
>>> export it, and use it from muxes_realize_done. This should help abstract
>>> away mux implementation.
>>>
>>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>> Reviewed-by: Eric Blake <eblake@redhat.com>
>>> ---
>>>  chardev/char-mux.h |  2 +-
>>>  chardev/char-mux.c | 11 ++++++++---
>>>  chardev/char.c     |  9 ++-------
>>>  3 files changed, 11 insertions(+), 11 deletions(-)
>>>
>>> diff --git a/chardev/char-mux.h b/chardev/char-mux.h
>>> index 9a2fffce91..3f41dfcfd2 100644
>>> --- a/chardev/char-mux.h
>>> +++ b/chardev/char-mux.h
>>> @@ -58,6 +58,6 @@ typedef struct MuxChardev {
>>>
>>>  void mux_chr_set_handlers(Chardev *chr, GMainContext *context);
>>>  void mux_set_focus(Chardev *chr, int focus);
>>> -void mux_chr_send_event(MuxChardev *d, int mux_nr, int event);
>>> +void mux_chr_send_all_event(Chardev *chr, int event);
>>>
>>>  #endif /* CHAR_MUX_H */
>>> diff --git a/chardev/char-mux.c b/chardev/char-mux.c
>>> index 5547a36a0a..37d42c65c6 100644
>>> --- a/chardev/char-mux.c
>>> +++ b/chardev/char-mux.c
>>> @@ -114,7 +114,7 @@ static void mux_print_help(Chardev *chr)
>>>      }
>>>  }
>>>
>>> -void mux_chr_send_event(MuxChardev *d, int mux_nr, int event)
>>> +static void mux_chr_send_event(MuxChardev *d, int mux_nr, int event)
>>>  {
>>>      CharBackend *be = d->backends[mux_nr];
>>>
>>> @@ -222,9 +222,9 @@ static void mux_chr_read(void *opaque, const uint8_t
>>> *buf, int size)
>>>
>>>  bool muxes_realized;
>>>
>>> -static void mux_chr_event(void *opaque, int event)
>>> +void mux_chr_send_all_event(Chardev *chr, int event)
>>>  {
>>> -    MuxChardev *d = MUX_CHARDEV(opaque);
>>> +    MuxChardev *d = MUX_CHARDEV(chr);
>>>      int i;
>>>
>>>      if (!muxes_realized) {
>>> @@ -237,6 +237,11 @@ static void mux_chr_event(void *opaque, int event)
>>>      }
>>>  }
>>>
>>> +static void mux_chr_event(void *opaque, int event)
>>
>> Why use an opaque pointer and not Chardev *chr here? Not a big deal but
>> it eases debugging sessions.
>> Anyway it'll be correctly displayed single-stepping in :)
>
> It's the signature of IOEventHandler, avoiding casting.

Sorry I missed qemu_chr_fe_set_handlers() use my bad!

>>
>> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
>>
>>> +{
>>> +    mux_chr_send_all_event(CHARDEV(opaque), event);
>>> +}
>>> +
>>>  static GSource *mux_chr_add_watch(Chardev *s, GIOCondition cond)
>>>  {
>>>      MuxChardev *d = MUX_CHARDEV(s);
>>> diff --git a/chardev/char.c b/chardev/char.c
>>> index aad639b620..674c097fbe 100644
>>> --- a/chardev/char.c
>>> +++ b/chardev/char.c
>>> @@ -451,22 +451,17 @@ static void muxes_realize_done(Notifier *notifier,
>>> void *unused)
>>>  {
>>>      Chardev *chr;
>>>
>>> +    muxes_realized = true;
>>>      QTAILQ_FOREACH(chr, &chardevs, next) {
>>>          if (CHARDEV_IS_MUX(chr)) {
>>> -            MuxChardev *d = MUX_CHARDEV(chr);
>>> -            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);
>>> -            }
>>> +            mux_chr_send_all_event(CHARDEV(chr), CHR_EVENT_OPENED);
>>>              /* mark mux as OPENED so any new FEs will immediately receive
>>>               * OPENED event
>>>               */
>>>              qemu_chr_be_event(chr, CHR_EVENT_OPENED);
>>>          }
>>>      }
>>> -    muxes_realized = true;
>>>  }
>>>
>>>  static Notifier muxes_realize_notify = {
>>>
>>
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9)
  2017-04-10 13:58 ` [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
@ 2017-04-18  9:50   ` Marc-André Lureau
  0 siblings, 0 replies; 33+ messages in thread
From: Marc-André Lureau @ 2017-04-18  9:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Eric Blake, Philippe Mathieu-Daudé

Hi

On Mon, Apr 10, 2017 at 5:58 PM Marc-André Lureau <
marcandre.lureau@gmail.com> wrote:

> On Thu, Mar 16, 2017 at 10:23 AM Marc-André Lureau <
> marcandre.lureau@redhat.com> wrote:
>
>> Hi,
>>
>> The following series contains various patches:
>> - replace "chardevs" list for a /chardevs container object
>> - add a few read-only socket properties mainly useful for testing
>> - some chardev related clean-ups
>> - add various chardev tests
>>
>> This series is part of a larger refactoring series that I try to keep
>> up to date here: https://github.com/elmarco/qemu/commits/chrfe
>>
>>
> ping (most of the patches are still unreviewed)
>

Patches missing reviews: 5-9, 12, 16-21

thanks

v3:
>> - open code object_new_with_props() as suggest by Paolo
>> - added some r-b tags
>> - rebased
>>
>> v2:
>> - replaced root container unref with a TODO
>> - call object_unparent() directly instead of qemu_chr_delete()
>> - remove bad qcow2 NULL check removal
>> - rebased
>>
>> Marc-André Lureau (21):
>>   char: remove qemu_chr_be_generic_open
>>   mux: simplfy muxes_realize_done
>>   xen: use a better chardev type check
>>   container: don't leak container reference
>>   char: add a /chardevs container
>>   vl: add todo note about root container cleanup
>>   char: use /chardevs container instead of chardevs list
>>   char: remove qemu_chardev_add
>>   char: remove chardevs list
>>   char: useless NULL check
>>   char-socket: introduce update_disconnected_filename()
>>   char-socket: update local address after listen
>>   char-socket: add 'addr' property
>>   char-socket: add 'connected' property
>>   char-udp: flush as much buffer as possible
>>   tests: add alias check in /char/ringbuf
>>   tests: add /char/pipe test
>>   tests: add /char/file test
>>   tests: add /char/socket test
>>   tests: add /char/udp test
>>   tests: add /char/console test
>>
>>  chardev/char-mux.h          |   2 +-
>>  include/sysemu/char.h       |  10 --
>>  chardev/char-mux.c          |  11 +-
>>  chardev/char-pty.c          |   2 +-
>>  chardev/char-socket.c       |  46 +++++-
>>  chardev/char-udp.c          |  26 ++--
>>  chardev/char.c              | 148 ++++++++----------
>>  gdbstub.c                   |   4 +-
>>  hw/usb/ccid-card-passthru.c |   2 +-
>>  hw/usb/redirect.c           |   2 +-
>>  net/vhost-user.c            |   2 +-
>>  qom/container.c             |   1 +
>>  tests/test-char.c           | 366
>> +++++++++++++++++++++++++++++++++++++++++++-
>>  tests/vhost-user-test.c     |   2 +-
>>  ui/console.c                |   2 +-
>>  ui/gtk.c                    |   2 +-
>>  vl.c                        |   1 +
>>  xen-common.c                |   2 +-
>>  18 files changed, 504 insertions(+), 127 deletions(-)
>>
>> --
>> 2.12.0.191.gc5d8de91d
>>
>>
>> --
> Marc-André Lureau
>
-- 
Marc-André Lureau

^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2017-04-18  9:50 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-16  9:21 [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 01/21] char: remove qemu_chr_be_generic_open Marc-André Lureau
2017-04-04 15:08   ` Philippe Mathieu-Daudé
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 02/21] mux: simplfy muxes_realize_done Marc-André Lureau
2017-04-04 15:14   ` Philippe Mathieu-Daudé
2017-04-04 16:31     ` Marc-André Lureau
2017-04-11  3:02       ` Philippe Mathieu-Daudé
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 03/21] xen: use a better chardev type check Marc-André Lureau
2017-04-04 15:15   ` Philippe Mathieu-Daudé
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 04/21] container: don't leak container reference Marc-André Lureau
2017-04-11  2:53   ` Philippe Mathieu-Daudé
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 05/21] char: add a /chardevs container Marc-André Lureau
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 06/21] vl: add todo note about root container cleanup Marc-André Lureau
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 07/21] char: use /chardevs container instead of chardevs list Marc-André Lureau
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 08/21] char: remove qemu_chardev_add Marc-André Lureau
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 09/21] char: remove chardevs list Marc-André Lureau
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 10/21] char: useless NULL check Marc-André Lureau
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 11/21] char-socket: introduce update_disconnected_filename() Marc-André Lureau
2017-04-11  2:56   ` Philippe Mathieu-Daudé
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 12/21] char-socket: update local address after listen Marc-André Lureau
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 13/21] char-socket: add 'addr' property Marc-André Lureau
2017-04-11  2:57   ` Philippe Mathieu-Daudé
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 14/21] char-socket: add 'connected' property Marc-André Lureau
2017-04-11  2:58   ` Philippe Mathieu-Daudé
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 15/21] char-udp: flush as much buffer as possible Marc-André Lureau
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 16/21] tests: add alias check in /char/ringbuf Marc-André Lureau
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 17/21] tests: add /char/pipe test Marc-André Lureau
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 18/21] tests: add /char/file test Marc-André Lureau
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 19/21] tests: add /char/socket test Marc-André Lureau
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 20/21] tests: add /char/udp test Marc-André Lureau
2017-03-16  9:21 ` [Qemu-devel] [PATCH v3 21/21] tests: add /char/console test Marc-André Lureau
2017-04-10 13:58 ` [Qemu-devel] [PATCH v3 00/21] chardev clean-ups & tests (after 2.9) Marc-André Lureau
2017-04-18  9:50   ` Marc-André Lureau

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.