diff mbox series

[RFC,v1,02/26] char-socket: allow vsock parameters (cid, port)

Message ID 20200415005938.23895-3-alazar@bitdefender.com
State New
Headers show
Series VM introspection | expand

Commit Message

Adalbert Lazăr April 15, 2020, 12:59 a.m. UTC
The introspection tool can run in a separate VM and the introspected
VM will establish a connection using a virtual socket.

CC: "Marc-André Lureau" <marcandre.lureau@redhat.com>
CC: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Adalbert Lazăr <alazar@bitdefender.com>
---
 chardev/char-socket.c | 27 ++++++++++++++++++++++++---
 chardev/char.c        |  3 +++
 2 files changed, 27 insertions(+), 3 deletions(-)

Comments

Marc-André Lureau April 15, 2020, 10:43 a.m. UTC | #1
Hi

On Wed, Apr 15, 2020 at 3:00 AM Adalbert Lazăr <alazar@bitdefender.com> wrote:
>
> The introspection tool can run in a separate VM and the introspected
> VM will establish a connection using a virtual socket.
>
> CC: "Marc-André Lureau" <marcandre.lureau@redhat.com>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Adalbert Lazăr <alazar@bitdefender.com>

We should also add QMP support.

Please add some tests in tests/test-char.c.

> ---
>  chardev/char-socket.c | 27 ++++++++++++++++++++++++---
>  chardev/char.c        |  3 +++
>  2 files changed, 27 insertions(+), 3 deletions(-)
>
> diff --git a/chardev/char-socket.c b/chardev/char-socket.c
> index bd966aace1..9b2deb0125 100644
> --- a/chardev/char-socket.c
> +++ b/chardev/char-socket.c
> @@ -23,6 +23,11 @@
>   */
>
>  #include "qemu/osdep.h"
> +
> +#ifdef CONFIG_AF_VSOCK
> +#include <linux/vm_sockets.h>
> +#endif /* CONFIG_AF_VSOCK */
> +
>  #include "chardev/char.h"
>  #include "io/channel-socket.h"
>  #include "io/channel-tls.h"
> @@ -590,6 +595,14 @@ static char *qemu_chr_compute_filename(SocketChardev *s)
>                                 s->is_listen ? ",server" : "",
>                                 left, phost, right, pserv);
>
> +#ifdef CONFIG_AF_VSOCK
> +    case AF_VSOCK:
> +        return g_strdup_printf("vsock:%d:%d%s",
> +                               ((struct sockaddr_vm *)(ss))->svm_cid,
> +                               ((struct sockaddr_vm *)(ss))->svm_port,
> +                               s->is_listen ? ",server" : "");
> +#endif
> +
>      default:
>          return g_strdup_printf("unknown");
>      }
> @@ -1378,18 +1391,19 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
>  {
>      const char *path = qemu_opt_get(opts, "path");
>      const char *host = qemu_opt_get(opts, "host");
> +    const char *cid  = qemu_opt_get(opts, "cid");
>      const char *port = qemu_opt_get(opts, "port");
>      const char *fd = qemu_opt_get(opts, "fd");
>      SocketAddressLegacy *addr;
>      ChardevSocket *sock;
>
> -    if ((!!path + !!fd + !!host) != 1) {
> +    if ((!!path + !!fd + !!host + !!cid) != 1) {
>          error_setg(errp,
> -                   "Exactly one of 'path', 'fd' or 'host' required");
> +                   "Exactly one of 'path', 'fd', 'cid' or 'host' required");
>          return;
>      }
>
> -    if (host && !port) {
> +    if ((host || cid) && !port) {
>          error_setg(errp, "chardev: socket: no port given");
>          return;
>      }
> @@ -1444,6 +1458,13 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
>              .has_ipv6 = qemu_opt_get(opts, "ipv6"),
>              .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
>          };
> +    } else if (cid) {
> +        addr->type = SOCKET_ADDRESS_LEGACY_KIND_VSOCK;
> +        addr->u.vsock.data = g_new0(VsockSocketAddress, 1);
> +        *addr->u.vsock.data = (VsockSocketAddress) {
> +            .cid  = g_strdup(cid),
> +            .port = g_strdup(port),
> +        };
>      } else if (fd) {
>          addr->type = SOCKET_ADDRESS_LEGACY_KIND_FD;
>          addr->u.fd.data = g_new(String, 1);
> diff --git a/chardev/char.c b/chardev/char.c
> index e77564060d..39e36ceb97 100644
> --- a/chardev/char.c
> +++ b/chardev/char.c
> @@ -852,6 +852,9 @@ QemuOptsList qemu_chardev_opts = {
>          },{
>              .name = "host",
>              .type = QEMU_OPT_STRING,
> +        },{
> +            .name = "cid",
> +            .type = QEMU_OPT_STRING,
>          },{
>              .name = "port",
>              .type = QEMU_OPT_STRING,
>
Adalbert Lazăr April 15, 2020, 12:09 p.m. UTC | #2
On Wed, 15 Apr 2020 12:43:31 +0200, Marc-André Lureau <marcandre.lureau@gmail.com> wrote:
> Hi
> 
> On Wed, Apr 15, 2020 at 3:00 AM Adalbert Lazăr <alazar@bitdefender.com> wrote:
> >
> > The introspection tool can run in a separate VM and the introspected
> > VM will establish a connection using a virtual socket.
> >
> > CC: "Marc-André Lureau" <marcandre.lureau@redhat.com>
> > CC: Paolo Bonzini <pbonzini@redhat.com>
> > Signed-off-by: Adalbert Lazăr <alazar@bitdefender.com>
> 
> We should also add QMP support.
> 

The virtual socket seems to be created with the next QMP command:

{
  "execute" : "chardev-add", "arguments" :
  {
     "id" : "id1", "backend" :
     {
        "type" : "socket", "data" :
        {
            "reconnect" : 10, "addr" :
            {
                "type" : "vsock", "data" : { "cid" : "321", "port" : "1234" }
            }
        }
     }
   }
}

From what I remember, only the creation from command line was missing.

> Please add some tests in tests/test-char.c.
> 

Sure.
Thanks.

> > ---
> >  chardev/char-socket.c | 27 ++++++++++++++++++++++++---
> >  chardev/char.c        |  3 +++
> >  2 files changed, 27 insertions(+), 3 deletions(-)
> >
> > diff --git a/chardev/char-socket.c b/chardev/char-socket.c
> > index bd966aace1..9b2deb0125 100644
> > --- a/chardev/char-socket.c
> > +++ b/chardev/char-socket.c
> > @@ -23,6 +23,11 @@
> >   */
> >
> >  #include "qemu/osdep.h"
> > +
> > +#ifdef CONFIG_AF_VSOCK
> > +#include <linux/vm_sockets.h>
> > +#endif /* CONFIG_AF_VSOCK */
> > +
> >  #include "chardev/char.h"
> >  #include "io/channel-socket.h"
> >  #include "io/channel-tls.h"
> > @@ -590,6 +595,14 @@ static char *qemu_chr_compute_filename(SocketChardev *s)
> >                                 s->is_listen ? ",server" : "",
> >                                 left, phost, right, pserv);
> >
> > +#ifdef CONFIG_AF_VSOCK
> > +    case AF_VSOCK:
> > +        return g_strdup_printf("vsock:%d:%d%s",
> > +                               ((struct sockaddr_vm *)(ss))->svm_cid,
> > +                               ((struct sockaddr_vm *)(ss))->svm_port,
> > +                               s->is_listen ? ",server" : "");
> > +#endif
> > +
> >      default:
> >          return g_strdup_printf("unknown");
> >      }
> > @@ -1378,18 +1391,19 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
> >  {
> >      const char *path = qemu_opt_get(opts, "path");
> >      const char *host = qemu_opt_get(opts, "host");
> > +    const char *cid  = qemu_opt_get(opts, "cid");
> >      const char *port = qemu_opt_get(opts, "port");
> >      const char *fd = qemu_opt_get(opts, "fd");
> >      SocketAddressLegacy *addr;
> >      ChardevSocket *sock;
> >
> > -    if ((!!path + !!fd + !!host) != 1) {
> > +    if ((!!path + !!fd + !!host + !!cid) != 1) {
> >          error_setg(errp,
> > -                   "Exactly one of 'path', 'fd' or 'host' required");
> > +                   "Exactly one of 'path', 'fd', 'cid' or 'host' required");
> >          return;
> >      }
> >
> > -    if (host && !port) {
> > +    if ((host || cid) && !port) {
> >          error_setg(errp, "chardev: socket: no port given");
> >          return;
> >      }
> > @@ -1444,6 +1458,13 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
> >              .has_ipv6 = qemu_opt_get(opts, "ipv6"),
> >              .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
> >          };
> > +    } else if (cid) {
> > +        addr->type = SOCKET_ADDRESS_LEGACY_KIND_VSOCK;
> > +        addr->u.vsock.data = g_new0(VsockSocketAddress, 1);
> > +        *addr->u.vsock.data = (VsockSocketAddress) {
> > +            .cid  = g_strdup(cid),
> > +            .port = g_strdup(port),
> > +        };
> >      } else if (fd) {
> >          addr->type = SOCKET_ADDRESS_LEGACY_KIND_FD;
> >          addr->u.fd.data = g_new(String, 1);
> > diff --git a/chardev/char.c b/chardev/char.c
> > index e77564060d..39e36ceb97 100644
> > --- a/chardev/char.c
> > +++ b/chardev/char.c
> > @@ -852,6 +852,9 @@ QemuOptsList qemu_chardev_opts = {
> >          },{
> >              .name = "host",
> >              .type = QEMU_OPT_STRING,
> > +        },{
> > +            .name = "cid",
> > +            .type = QEMU_OPT_STRING,
> >          },{
> >              .name = "port",
> >              .type = QEMU_OPT_STRING,
> >
> 
> 
> -- 
> Marc-André Lureau
diff mbox series

Patch

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index bd966aace1..9b2deb0125 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -23,6 +23,11 @@ 
  */
 
 #include "qemu/osdep.h"
+
+#ifdef CONFIG_AF_VSOCK
+#include <linux/vm_sockets.h>
+#endif /* CONFIG_AF_VSOCK */
+
 #include "chardev/char.h"
 #include "io/channel-socket.h"
 #include "io/channel-tls.h"
@@ -590,6 +595,14 @@  static char *qemu_chr_compute_filename(SocketChardev *s)
                                s->is_listen ? ",server" : "",
                                left, phost, right, pserv);
 
+#ifdef CONFIG_AF_VSOCK
+    case AF_VSOCK:
+        return g_strdup_printf("vsock:%d:%d%s",
+                               ((struct sockaddr_vm *)(ss))->svm_cid,
+                               ((struct sockaddr_vm *)(ss))->svm_port,
+                               s->is_listen ? ",server" : "");
+#endif
+
     default:
         return g_strdup_printf("unknown");
     }
@@ -1378,18 +1391,19 @@  static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
 {
     const char *path = qemu_opt_get(opts, "path");
     const char *host = qemu_opt_get(opts, "host");
+    const char *cid  = qemu_opt_get(opts, "cid");
     const char *port = qemu_opt_get(opts, "port");
     const char *fd = qemu_opt_get(opts, "fd");
     SocketAddressLegacy *addr;
     ChardevSocket *sock;
 
-    if ((!!path + !!fd + !!host) != 1) {
+    if ((!!path + !!fd + !!host + !!cid) != 1) {
         error_setg(errp,
-                   "Exactly one of 'path', 'fd' or 'host' required");
+                   "Exactly one of 'path', 'fd', 'cid' or 'host' required");
         return;
     }
 
-    if (host && !port) {
+    if ((host || cid) && !port) {
         error_setg(errp, "chardev: socket: no port given");
         return;
     }
@@ -1444,6 +1458,13 @@  static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
             .has_ipv6 = qemu_opt_get(opts, "ipv6"),
             .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
         };
+    } else if (cid) {
+        addr->type = SOCKET_ADDRESS_LEGACY_KIND_VSOCK;
+        addr->u.vsock.data = g_new0(VsockSocketAddress, 1);
+        *addr->u.vsock.data = (VsockSocketAddress) {
+            .cid  = g_strdup(cid),
+            .port = g_strdup(port),
+        };
     } else if (fd) {
         addr->type = SOCKET_ADDRESS_LEGACY_KIND_FD;
         addr->u.fd.data = g_new(String, 1);
diff --git a/chardev/char.c b/chardev/char.c
index e77564060d..39e36ceb97 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -852,6 +852,9 @@  QemuOptsList qemu_chardev_opts = {
         },{
             .name = "host",
             .type = QEMU_OPT_STRING,
+        },{
+            .name = "cid",
+            .type = QEMU_OPT_STRING,
         },{
             .name = "port",
             .type = QEMU_OPT_STRING,