Patchwork [RFC,v3,18/21] virtproxy: qemu integration, add virtproxy chardev

login
register
mail settings
Submitter Michael Roth
Date Nov. 16, 2010, 1:16 a.m.
Message ID <1289870175-14880-19-git-send-email-mdroth@linux.vnet.ibm.com>
Download mbox | patch
Permalink /patch/71343/
State New
Headers show

Comments

Michael Roth - Nov. 16, 2010, 1:16 a.m.
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 <mdroth@linux.vnet.ibm.com>
---
 qemu-char.c   |  130 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qemu-config.c |    6 +++
 2 files changed, 136 insertions(+), 0 deletions(-)
Jes Sorensen - Nov. 18, 2010, 11:47 a.m.
On 11/16/10 02:16, Michael Roth wrote:
> 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 <mdroth@linux.vnet.ibm.com>
> ---
>  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;

-1 again

Cheers,
Jes

Patch

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 */ }
     },