Patchwork [RFC,v4,03/18] virtagent: qemu-vp, integrate virtagent server

login
register
mail settings
Submitter Michael Roth
Date Nov. 16, 2010, 4:01 p.m.
Message ID <1289923320-5638-4-git-send-email-mdroth@linux.vnet.ibm.com>
Download mbox | patch
Permalink /patch/71412/
State New
Headers show

Comments

Michael Roth - Nov. 16, 2010, 4:01 p.m.
This allows the guest RPC server to be integrated into the
qemu-vp/virtproxy i/o loop

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 qemu-char.c   |   26 ++++++++++++++++
 qemu-config.c |    3 ++
 qemu-vp.c     |   94 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 114 insertions(+), 9 deletions(-)
Jes Sorensen - Nov. 18, 2010, 2:02 p.m.
On 11/16/10 17:01, Michael Roth wrote:
> +    bool enable_virtagent;
>  
>      chr->opaque = drv;
>      chr->chr_write = vp_chr_write;
> @@ -2025,9 +2029,31 @@ static CharDriverState *qemu_chr_open_virtproxy(QemuOpts *opts)
>      /* parse socket forwarding options */
>      qemu_opt_foreach(opts, vp_init_forwards, drv, 1);
>  
> +    /* add forwarding options to enable virtagent server */
> +    enable_virtagent = qemu_opt_get_bool(opts, "virtagent", 0);

int qemu_opt_get_bool(QemuOpts *opts, const char *name, int defval)

Sorry qemu_opt_get_bool() actually returns an int.

> diff --git a/qemu-vp.c b/qemu-vp.c
> index cfd2a69..38959e5 100644
> --- a/qemu-vp.c
> +++ b/qemu-vp.c
> @@ -37,6 +37,8 @@
>  #include "qemu-option.h"
>  #include "qemu_socket.h"
>  #include "virtproxy.h"
> +#include "virtagent.h"
> +#include "virtagent-daemon.h"
>  
>  static bool verbose_enabled = 0;

You don't need to initialize global variables to zero, the compiler does
that.


> +static int init_agent(const VPData *agent_iforward) {
> +    QemuOpts *opts = agent_iforward->opts;
> +    VPDriver *drv;
> +    int ret, index;
> +
> +    INFO("initializing agent...");
> +    if (verbose_enabled) {
> +        qemu_opts_print(opts, NULL);
> +    }
> +
> +    index = qemu_opt_get_number(agent_iforward->opts, "index", 0);
> +    drv = get_channel_drv(index);
> +    if (drv == NULL) {
> +        warnx("unable to find channel with index: %d", index);
> +        goto err;
> +    }
> +
> +    /* outbound RPCs */
> +    ret = va_client_init(drv, false);
> +    if (ret) {
> +        warnx("error starting RPC server");
> +        goto err;
> +    }
> +
> +    /* start guest RPC server */
> +    ret = va_server_init(drv, false);
> +    if (ret != 0) {
> +        warnx("error starting RPC server");
> +        goto err;
> +    }
> +
> +    return 0;
> +
> +err:
> +    return -1;
> +}

Please set appropriate error codes and return something meaningful
instead of just -1.

Cheers,
Jes

Patch

diff --git a/qemu-char.c b/qemu-char.c
index bc7925c..fd02640 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -1905,6 +1905,8 @@  return_err:
 /* Virtproxy chardev driver */
 
 #include "virtproxy.h"
+#include "virtagent.h"
+#include "virtagent-daemon.h"
 
 static int vp_init_oforward(VPDriver *drv, QemuOpts *opts)
 {
@@ -2016,6 +2018,8 @@  static CharDriverState *qemu_chr_open_virtproxy(QemuOpts *opts)
 {
     CharDriverState *chr = qemu_mallocz(sizeof(CharDriverState));
     VPDriver *drv = vp_new(VP_CTX_CHARDEV, chr, 0, 0);
+    int ret;
+    bool enable_virtagent;
 
     chr->opaque = drv;
     chr->chr_write = vp_chr_write;
@@ -2025,9 +2029,31 @@  static CharDriverState *qemu_chr_open_virtproxy(QemuOpts *opts)
     /* parse socket forwarding options */
     qemu_opt_foreach(opts, vp_init_forwards, drv, 1);
 
+    /* add forwarding options to enable virtagent server */
+    enable_virtagent = qemu_opt_get_bool(opts, "virtagent", 0);
+    if (enable_virtagent) {
+        /* outbound RPCs */
+        ret = va_client_init(drv, true);
+        if (ret) {
+            fprintf(stderr, "error enabling virtagent client");
+            goto fail;
+        }
+        /* inbound RPCs */
+        ret = va_server_init(drv, true);
+        if (ret) {
+            fprintf(stderr, "error enabling virtagent server");
+            goto fail;
+        }
+    }
+
     /* for "info chardev" monitor command */
     chr->filename = NULL;
     return chr;
+
+fail:
+    qemu_free(drv);
+    qemu_free(chr);
+    return NULL;
 }
 
 /***********************************************************/
diff --git a/qemu-config.c b/qemu-config.c
index 400e61a..41ba54d 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -152,6 +152,9 @@  static QemuOptsList qemu_chardev_opts = {
         },{
             .name = "iforward",
             .type = QEMU_OPT_STRING,
+        },{
+            .name = "virtagent",
+            .type = QEMU_OPT_BOOL,
         },
         { /* end of list */ }
     },
diff --git a/qemu-vp.c b/qemu-vp.c
index cfd2a69..38959e5 100644
--- a/qemu-vp.c
+++ b/qemu-vp.c
@@ -37,6 +37,8 @@ 
 #include "qemu-option.h"
 #include "qemu_socket.h"
 #include "virtproxy.h"
+#include "virtagent.h"
+#include "virtagent-daemon.h"
 
 static bool verbose_enabled = 0;
 #define DEBUG_ENABLED
@@ -219,14 +221,16 @@  static void usage(const char *cmd)
 "[-o <oforward_opts> ...]\n"
 "QEMU virt-proxy communication channel\n"
 "\n"
-"  -c, --channel    channel options of the form:\n"
-"                   <method>:<addr>:<port>[:channel_id]\n"
-"  -o, --oforward   oforward options of the form:\n"
-"                   <service_id>:<addr>:<port>[:channel_id]\n"
-"  -i, --iforward   iforward options of the form:\n"
-"                   <service_id>:<addr>:<port>[:channel_id]\n"
-"  -v, --verbose    display extra debugging information\n"
-"  -h, --help       display this help and exit\n"
+"  -c, --channel     channel options of the form:\n"
+"                    <method>:<addr>:<port>[:channel_id]\n"
+"  -g, --guest-agent guest rpc server, options of the form:\n"
+"                    [channel_id]\n"
+"  -o, --oforward    oforward options of the form:\n"
+"                    <service_id>:<addr>:<port>[:channel_id]\n"
+"  -i, --iforward    iforward options of the form:\n"
+"                    <service_id>:<addr>:<port>[:channel_id]\n"
+"  -v, --verbose     display extra debugging information\n"
+"  -h, --help        display this help and exit\n"
 "\n"
 "  channels are used to establish a data connection between 2 end-points in\n"
 "  the host or the guest (connection method specified by <method>).\n"
@@ -426,13 +430,52 @@  static int init_iforwards(void) {
     return 0;
 }
 
+static int init_agent(const VPData *agent_iforward) {
+    QemuOpts *opts = agent_iforward->opts;
+    VPDriver *drv;
+    int ret, index;
+
+    INFO("initializing agent...");
+    if (verbose_enabled) {
+        qemu_opts_print(opts, NULL);
+    }
+
+    index = qemu_opt_get_number(agent_iforward->opts, "index", 0);
+    drv = get_channel_drv(index);
+    if (drv == NULL) {
+        warnx("unable to find channel with index: %d", index);
+        goto err;
+    }
+
+    /* outbound RPCs */
+    ret = va_client_init(drv, false);
+    if (ret) {
+        warnx("error starting RPC server");
+        goto err;
+    }
+
+    /* start guest RPC server */
+    ret = va_server_init(drv, false);
+    if (ret != 0) {
+        warnx("error starting RPC server");
+        goto err;
+    }
+
+    return 0;
+
+err:
+    return -1;
+}
+
 int main(int argc, char **argv)
 {
-    const char *sopt = "hVvi:o:c:";
+    const char *sopt = "hVvi:o:c:g::p::";
     struct option lopt[] = {
         { "help", 0, NULL, 'h' },
         { "version", 0, NULL, 'V' },
         { "verbose", 0, NULL, 'v' },
+        { "host-agent", 0, NULL, 'p' },
+        { "guest-agent", 0, NULL, 'g' },
         { "iforward", 0, NULL, 'i' },
         { "oforward", 0, NULL, 'o' },
         { "channel", 0, NULL, 'c' },
@@ -442,10 +485,12 @@  int main(int argc, char **argv)
     QTAILQ_INIT(&iforwards);
     QTAILQ_INIT(&oforwards);
     QTAILQ_INIT(&channels);
+    VPData *guest_agent_iforward = NULL;
 
     while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
         QemuOpts *opts;
         VPData *data;
+        char optarg_tmp[VP_ARG_LEN];
         switch (ch) {
         case 'i':
             opts = qemu_opts_create(&vp_opts, NULL, 0);
@@ -477,6 +522,28 @@  int main(int argc, char **argv)
             data->opts = opts;
             QTAILQ_INSERT_TAIL(&channels, data, next);
             break;
+        case 'g':
+            /* create pre-baked iforward for guest agent */
+            if (guest_agent_iforward) {
+                errx(EXIT_FAILURE, "only one --guest-agent argument allowed");
+            }
+            opts = qemu_opts_create(&vp_opts, NULL, 0);
+            if (optarg == 0) {
+                sprintf(optarg_tmp, "%s:%s:-", GUEST_AGENT_SERVICE_ID,
+                                     GUEST_AGENT_PATH);
+            } else {
+                sprintf(optarg_tmp, "%s:%s:-:%d", GUEST_AGENT_SERVICE_ID,
+                                     GUEST_AGENT_PATH, atoi(optarg));
+            }
+            ret = vp_parse(opts, optarg_tmp, 0);
+            if (ret) {
+                errx(EXIT_FAILURE, "error parsing arg: %s", optarg);
+            }
+            data = qemu_mallocz(sizeof(VPData));
+            data->opts = opts;
+            QTAILQ_INSERT_TAIL(&iforwards, data, next);
+            guest_agent_iforward = data;
+            break;
         case 'v':
             verbose_enabled = 1;
             break;
@@ -506,6 +573,15 @@  int main(int argc, char **argv)
              "error initializing service mappings for incoming connections");
     }
 
+
+    if (guest_agent_iforward) {
+        ret = init_agent(guest_agent_iforward);
+        if (ret) {
+            errx(EXIT_FAILURE,
+                 "error initializing guest agent");
+        }
+    }
+
     /* main i/o loop */
     for (;;) {
         DEBUG("entering main_loop_wait()");