Patchwork [2/9] chardev: add mux chardev support to qapi

login
register
mail settings
Submitter Gerd Hoffmann
Date Feb. 25, 2013, 9:03 a.m.
Message ID <1361783023-10082-4-git-send-email-kraxel@redhat.com>
Download mbox | patch
Permalink /patch/222878/
State New
Headers show

Comments

Gerd Hoffmann - Feb. 25, 2013, 9:03 a.m.
This adds mux chardev support to the qapi and also makes the qapi-based
chardev creation path handle the "mux=on" option correctly.
---
 qapi-schema.json |   14 +++++++++++++-
 qemu-char.c      |   35 ++++++++++++++++++++++++++++++++---
 2 files changed, 45 insertions(+), 4 deletions(-)

Patch

diff --git a/qapi-schema.json b/qapi-schema.json
index cd7ea25..d633e1f 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3135,6 +3135,17 @@ 
                                      '*telnet'  : 'bool' } }
 
 ##
+# @ChardevMux:
+#
+# Configuration info for mux chardevs.
+#
+# @chardev: name of the base chardev.
+#
+# Since: 1.5
+##
+{ 'type': 'ChardevMux', 'data': { 'chardev' : 'str' } }
+
+##
 # @ChardevBackend:
 #
 # Configuration info for the new chardev backend.
@@ -3148,7 +3159,8 @@ 
                                        'parallel': 'ChardevHostdev',
                                        'socket' : 'ChardevSocket',
                                        'pty'    : 'ChardevDummy',
-                                       'null'   : 'ChardevDummy' } }
+                                       'null'   : 'ChardevDummy',
+                                       'mux'    : 'ChardevMux' } }
 
 ##
 # @ChardevReturn:
diff --git a/qemu-char.c b/qemu-char.c
index cf6b98b..fc908fa 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3049,6 +3049,11 @@  CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
         ChardevBackend *backend = g_new0(ChardevBackend, 1);
         ChardevReturn *ret = NULL;
         const char *id = qemu_opts_id(opts);
+        const char *bid = NULL;
+
+        if (qemu_opt_get_bool(opts, "mux", 0)) {
+            bid = g_strdup_printf("%s-base", id);
+        }
 
         chr = NULL;
         backend->kind = backend_table[i].kind;
@@ -3058,10 +3063,24 @@  CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
                 goto qapi_out;
             }
         }
-        ret = qmp_chardev_add(qemu_opts_id(opts), backend, errp);
+        ret = qmp_chardev_add(bid ? bid : id, backend, errp);
         if (error_is_set(errp)) {
             goto qapi_out;
         }
+
+        if (bid) {
+            qapi_free_ChardevBackend(backend);
+            qapi_free_ChardevReturn(ret);
+            backend = g_new0(ChardevBackend, 1);
+            backend->mux = g_new0(ChardevMux, 1);
+            backend->kind = CHARDEV_BACKEND_KIND_MUX;
+            backend->mux->chardev = g_strdup(bid);
+            ret = qmp_chardev_add(id, backend, errp);
+            if (error_is_set(errp)) {
+                goto qapi_out;
+            }
+        }
+
         chr = qemu_chr_find(id);
 
     qapi_out:
@@ -3411,7 +3430,7 @@  ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
                                Error **errp)
 {
     ChardevReturn *ret = g_new0(ChardevReturn, 1);
-    CharDriverState *chr = NULL;
+    CharDriverState *base, *chr = NULL;
 
     chr = qemu_chr_find(id);
     if (chr) {
@@ -3449,6 +3468,15 @@  ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
     case CHARDEV_BACKEND_KIND_NULL:
         chr = qemu_chr_open_null(NULL);
         break;
+    case CHARDEV_BACKEND_KIND_MUX:
+        base = qemu_chr_find(backend->mux->chardev);
+        if (base == NULL) {
+            error_setg(errp, "mux: base chardev %s not found",
+                       backend->mux->chardev);
+            break;
+        }
+        chr = qemu_chr_open_mux(base);
+        break;
     default:
         error_setg(errp, "unknown chardev backend (%d)", backend->kind);
         break;
@@ -3459,7 +3487,8 @@  ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
     }
     if (chr) {
         chr->label = g_strdup(id);
-        chr->avail_connections = 1;
+        chr->avail_connections =
+            (backend->kind == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1;
         QTAILQ_INSERT_TAIL(&chardevs, chr, next);
         return ret;
     } else {