qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC][PATCH v3 18/21] virtproxy: qemu integration, add virt


From: Michael Roth
Subject: [Qemu-devel] [RFC][PATCH v3 18/21] virtproxy: qemu integration, add virtproxy chardev
Date: Mon, 15 Nov 2010 19:16:12 -0600

This allows us to create a virtproxy instance via a chardev. It can now
be created with something like:

qemu -chardev virtproxy,id=vp1 \
     -device virtio-serial \
     -device virtserialport,chardev=vp1

In the future the ability to add oforwards/iforwards in the command-line
invocation and the monitor will be added. For now we leave it to users
of virtproxy (currently only virtagent) to set up the forwarding
sockets/ports they need via direct virtproxy API calls.

Signed-off-by: Michael Roth <address@hidden>
---
 qemu-char.c   |  130 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qemu-config.c |    6 +++
 2 files changed, 136 insertions(+), 0 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index 88997f9..bc7925c 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -1902,6 +1902,135 @@ return_err:
 }
 
 /***********************************************************/
+/* Virtproxy chardev driver */
+
+#include "virtproxy.h"
+
+static int vp_init_oforward(VPDriver *drv, QemuOpts *opts)
+{
+    int ret, fd;
+    const char *service_id;
+
+    if (qemu_opt_get(opts, "host") != NULL) {
+        fd = inet_listen_opts(opts, 0);
+    } else if (qemu_opt_get(opts, "path") != NULL) {
+        fd = unix_listen_opts(opts);
+    } else {
+        fprintf(stderr, "unable to find listening socket host/addr info");
+        return -1;
+    }
+
+    if (fd == -1) {
+        fprintf(stderr, "failed to create FD");
+        return -1;
+    }
+
+    service_id = qemu_opt_get(opts, "service_id");
+    if (service_id == NULL) {
+        fprintf(stderr, "no service_id specified");
+        return -1;
+    }
+
+    ret = vp_set_oforward(drv, fd, service_id);
+    if (ret != 0) {
+        fprintf(stderr, "error adding iforward");
+        return -1;
+    }
+
+    return 0;
+}
+
+static int vp_init_iforward(VPDriver *drv, QemuOpts *opts)
+{
+    const char *service_id, *addr, *port;
+    bool ipv6;
+    int ret;
+
+    service_id = qemu_opt_get(opts, "service_id");
+    if (service_id == NULL) {
+        fprintf(stderr, "no service_id specified");
+        return -1;
+    }
+    addr = qemu_opt_get(opts, "path");
+    port = NULL;
+    if (addr == NULL) {
+        /* map service to a network socket instead */
+        addr = qemu_opt_get(opts, "host");
+        port = qemu_opt_get(opts, "port");
+    }
+
+    ipv6 = qemu_opt_get_bool(opts, "ipv6", 0) ?
+           true : false;
+
+    ret = vp_set_iforward(drv, service_id, addr, port, ipv6);
+    if (ret != 0) {
+        fprintf(stderr, "error adding iforward");
+        return -1;
+    }
+
+    return 0;
+}
+
+static int vp_init_forwards(const char *name, const char *value, void *opaque)
+{
+    QemuOpts *opts = qemu_opts_create(&vp_opts, NULL, 0);
+    VPDriver *drv = opaque;
+    int ret;
+
+    if (strcmp(name, "oforward") != 0 && strcmp(name, "iforward") != 0) {
+        return 0;
+    }
+
+    /* parse opt string into QemuOpts */
+    ret = vp_parse(opts, value, 0);
+    if (ret < 0) {
+        fprintf(stderr, "error parsing virtproxy arguments");
+        return -1;
+    }
+
+    if (strcmp(name, "oforward") == 0) {
+        return vp_init_oforward(drv, opts);
+    } else if (strcmp(name, "iforward")) {
+        return vp_init_iforward(drv, opts);
+    }
+
+    return -1;
+}
+
+static int vp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
+{
+    VPDriver *drv = chr->opaque;
+    int ret;
+
+    fprintf(stderr, "called, opaque: %p\n", chr);
+
+    ret = vp_handle_packet_buf(drv, buf, len);
+    if (ret == -1) {
+        fprintf(stderr, "error handling data from virtproxy channel");
+    }
+
+    return 0;
+}
+
+static CharDriverState *qemu_chr_open_virtproxy(QemuOpts *opts)
+{
+    CharDriverState *chr = qemu_mallocz(sizeof(CharDriverState));
+    VPDriver *drv = vp_new(VP_CTX_CHARDEV, chr, 0, 0);
+
+    chr->opaque = drv;
+    chr->chr_write = vp_chr_write;
+
+    qemu_chr_generic_open(chr);
+
+    /* parse socket forwarding options */
+    qemu_opt_foreach(opts, vp_init_forwards, drv, 1);
+
+    /* for "info chardev" monitor command */
+    chr->filename = NULL;
+    return chr;
+}
+
+/***********************************************************/
 /* TCP Net console */
 
 typedef struct {
@@ -2408,6 +2537,7 @@ static const struct {
     { .name = "udp",       .open = qemu_chr_open_udp },
     { .name = "msmouse",   .open = qemu_chr_open_msmouse },
     { .name = "vc",        .open = text_console_init },
+    { .name = "virtproxy", .open = qemu_chr_open_virtproxy },
 #ifdef _WIN32
     { .name = "file",      .open = qemu_chr_open_win_file_out },
     { .name = "pipe",      .open = qemu_chr_open_win_pipe },
diff --git a/qemu-config.c b/qemu-config.c
index 52f18be..400e61a 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -146,6 +146,12 @@ static QemuOptsList qemu_chardev_opts = {
         },{
             .name = "signal",
             .type = QEMU_OPT_BOOL,
+        },{
+            .name = "oforward",
+            .type = QEMU_OPT_STRING,
+        },{
+            .name = "iforward",
+            .type = QEMU_OPT_STRING,
         },
         { /* end of list */ }
     },
-- 
1.7.0.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]