qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL for-2.8 0/5] qemu-ga patch queue for 2.8
@ 2016-11-01  0:59 Michael Roth
  2016-11-01  0:59 ` [Qemu-devel] [PULL for-2.8 1/5] qga: minimal support for fstrim for Windows guests Michael Roth
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Michael Roth @ 2016-11-01  0:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

The following changes since commit e80b4b8fb6babce7dcc91ea9ddeecbc351fd4646:

  Merge remote-tracking branch 'remotes/awilliam/tags/vfio-updates-20161031.0' into staging (2016-10-31 18:19:06 +0000)

are available in the git repository at:


  git://github.com/mdroth/qemu.git tags/qga-pull-2016-10-31-tag

for you to fetch changes up to 586ef5dee77180fc32e33bc08051600030630239:

  qga: add vsock-listen method (2016-10-31 19:49:33 -0500)

----------------------------------------------------------------
qemu-ga patch queue for 2.8

* add guest-fstrim support for w32
* add support for using virtio-vsock as the communication channel

----------------------------------------------------------------
Denis V. Lunev (1):
      qga: minimal support for fstrim for Windows guests

Stefan Hajnoczi (4):
      qga: drop unused sockaddr in accept(2) call
      qga: drop unnecessary GA_CHANNEL_UNIX_LISTEN checks
      sockets: add AF_VSOCK support
      qga: add vsock-listen method

 configure            |  31 +++++++
 qapi-schema.json     |  23 +++++-
 qga/channel-posix.c  |  36 ++++++--
 qga/channel.h        |   1 +
 qga/commands-win32.c |  97 +++++++++++++++++++++-
 qga/main.c           |   6 +-
 util/qemu-sockets.c  | 227 +++++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 407 insertions(+), 14 deletions(-)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PULL for-2.8 1/5] qga: minimal support for fstrim for Windows guests
  2016-11-01  0:59 [Qemu-devel] [PULL for-2.8 0/5] qemu-ga patch queue for 2.8 Michael Roth
@ 2016-11-01  0:59 ` Michael Roth
  2016-11-01  0:59 ` [Qemu-devel] [PULL for-2.8 2/5] qga: drop unused sockaddr in accept(2) call Michael Roth
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Michael Roth @ 2016-11-01  0:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, Denis V. Lunev, Denis Plotnikov, Stefan Weil,
	Marc-André Lureau

From: "Denis V. Lunev" <den@openvz.org>

Unfortunately, there is no public Windows API to start trimming the
filesystem. The only viable way here is to call 'defrag.exe /L' for
each volume.

This is working since Win8 and Win2k12.

Signed-off-by: Denis V. Lunev <den@openvz.org>
Signed-off-by: Denis Plotnikov <dplotnikov@virtuozzo.com>
CC: Michael Roth <mdroth@linux.vnet.ibm.com>
CC: Stefan Weil <sw@weilnetz.de>
CC: Marc-André Lureau <marcandre.lureau@gmail.com>
* check g_utf16_to_utf8() return value for GError handling instead
  of GError directly (Marc-André)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 qga/commands-win32.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 94 insertions(+), 3 deletions(-)

diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 9c9be12..19d72b2 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -840,8 +840,99 @@ static void guest_fsfreeze_cleanup(void)
 GuestFilesystemTrimResponse *
 qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
 {
-    error_setg(errp, QERR_UNSUPPORTED);
-    return NULL;
+    GuestFilesystemTrimResponse *resp;
+    HANDLE handle;
+    WCHAR guid[MAX_PATH] = L"";
+
+    handle = FindFirstVolumeW(guid, ARRAYSIZE(guid));
+    if (handle == INVALID_HANDLE_VALUE) {
+        error_setg_win32(errp, GetLastError(), "failed to find any volume");
+        return NULL;
+    }
+
+    resp = g_new0(GuestFilesystemTrimResponse, 1);
+
+    do {
+        GuestFilesystemTrimResult *res;
+        GuestFilesystemTrimResultList *list;
+        PWCHAR uc_path;
+        DWORD char_count = 0;
+        char *path, *out;
+        GError *gerr = NULL;
+        gchar * argv[4];
+
+        GetVolumePathNamesForVolumeNameW(guid, NULL, 0, &char_count);
+
+        if (GetLastError() != ERROR_MORE_DATA) {
+            continue;
+        }
+        if (GetDriveTypeW(guid) != DRIVE_FIXED) {
+            continue;
+        }
+
+        uc_path = g_malloc(sizeof(WCHAR) * char_count);
+        if (!GetVolumePathNamesForVolumeNameW(guid, uc_path, char_count,
+                                              &char_count) || !*uc_path) {
+            /* strange, but this condition could be faced even with size == 2 */
+            g_free(uc_path);
+            continue;
+        }
+
+        res = g_new0(GuestFilesystemTrimResult, 1);
+
+        path = g_utf16_to_utf8(uc_path, char_count, NULL, NULL, &gerr);
+
+        g_free(uc_path);
+
+        if (!path) {
+            res->has_error = true;
+            res->error = g_strdup(gerr->message);
+            g_error_free(gerr);
+            break;
+        }
+
+        res->path = path;
+
+        list = g_new0(GuestFilesystemTrimResultList, 1);
+        list->value = res;
+        list->next = resp->paths;
+
+        resp->paths = list;
+
+        memset(argv, 0, sizeof(argv));
+        argv[0] = (gchar *)"defrag.exe";
+        argv[1] = (gchar *)"/L";
+        argv[2] = path;
+
+        if (!g_spawn_sync(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
+                          &out /* stdout */, NULL /* stdin */,
+                          NULL, &gerr)) {
+            res->has_error = true;
+            res->error = g_strdup(gerr->message);
+            g_error_free(gerr);
+        } else {
+            /* defrag.exe is UGLY. Exit code is ALWAYS zero.
+               Error is reported in the output with something like
+               (x89000020) etc code in the stdout */
+
+            int i;
+            gchar **lines = g_strsplit(out, "\r\n", 0);
+            g_free(out);
+
+            for (i = 0; lines[i] != NULL; i++) {
+                if (g_strstr_len(lines[i], -1, "(0x") == NULL) {
+                    continue;
+                }
+                res->has_error = true;
+                res->error = g_strdup(lines[i]);
+                break;
+            }
+            g_strfreev(lines);
+        }
+    } while (FindNextVolumeW(handle, guid, ARRAYSIZE(guid)));
+
+    FindVolumeClose(handle);
+    return resp;
 }
 
 typedef enum {
@@ -1416,7 +1507,7 @@ GList *ga_command_blacklist_init(GList *blacklist)
         "guest-get-memory-blocks", "guest-set-memory-blocks",
         "guest-get-memory-block-size",
         "guest-fsfreeze-freeze-list",
-        "guest-fstrim", NULL};
+        NULL};
     char **p = (char **)list_unsupported;
 
     while (*p) {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PULL for-2.8 2/5] qga: drop unused sockaddr in accept(2) call
  2016-11-01  0:59 [Qemu-devel] [PULL for-2.8 0/5] qemu-ga patch queue for 2.8 Michael Roth
  2016-11-01  0:59 ` [Qemu-devel] [PULL for-2.8 1/5] qga: minimal support for fstrim for Windows guests Michael Roth
@ 2016-11-01  0:59 ` Michael Roth
  2016-11-01  0:59 ` [Qemu-devel] [PULL for-2.8 3/5] qga: drop unnecessary GA_CHANNEL_UNIX_LISTEN checks Michael Roth
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Michael Roth @ 2016-11-01  0:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Stefan Hajnoczi

From: Stefan Hajnoczi <stefanha@redhat.com>

ga_channel_listen_accept() is currently hard-coded to support only
AF_UNIX because the struct sockaddr_un type is used.  This function
should work with any address family.

Drop the sockaddr since the client address is unused and is an optional
argument to accept(2).

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 qga/channel-posix.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/qga/channel-posix.c b/qga/channel-posix.c
index bb65d8b..bf32158 100644
--- a/qga/channel-posix.c
+++ b/qga/channel-posix.c
@@ -26,13 +26,10 @@ static gboolean ga_channel_listen_accept(GIOChannel *channel,
     GAChannel *c = data;
     int ret, client_fd;
     bool accepted = false;
-    struct sockaddr_un addr;
-    socklen_t addrlen = sizeof(addr);
 
     g_assert(channel != NULL);
 
-    client_fd = qemu_accept(g_io_channel_unix_get_fd(channel),
-                            (struct sockaddr *)&addr, &addrlen);
+    client_fd = qemu_accept(g_io_channel_unix_get_fd(channel), NULL, NULL);
     if (client_fd == -1) {
         g_warning("error converting fd to gsocket: %s", strerror(errno));
         goto out;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PULL for-2.8 3/5] qga: drop unnecessary GA_CHANNEL_UNIX_LISTEN checks
  2016-11-01  0:59 [Qemu-devel] [PULL for-2.8 0/5] qemu-ga patch queue for 2.8 Michael Roth
  2016-11-01  0:59 ` [Qemu-devel] [PULL for-2.8 1/5] qga: minimal support for fstrim for Windows guests Michael Roth
  2016-11-01  0:59 ` [Qemu-devel] [PULL for-2.8 2/5] qga: drop unused sockaddr in accept(2) call Michael Roth
@ 2016-11-01  0:59 ` Michael Roth
  2016-11-01  0:59 ` [Qemu-devel] [PULL for-2.8 4/5] sockets: add AF_VSOCK support Michael Roth
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Michael Roth @ 2016-11-01  0:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Stefan Hajnoczi

From: Stefan Hajnoczi <stefanha@redhat.com>

Throughout the code there are c->listen_channel checks which manage the
listen socket file descriptor (waiting for accept(2), closing the file
descriptor, etc).  These checks are currently preceded by explicit
c->method == GA_CHANNEL_UNIX_LISTEN checks.

Explicit GA_CHANNEL_UNIX_LISTEN checks are not necessary since serial
channel types do not create the listen channel (c->listen_channel).

As more listen channel types are added, explicitly checking all of them
becomes messy.  Rely on c->listen_channel to determine whether or not a
listen socket file descriptor is used.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 qga/channel-posix.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/qga/channel-posix.c b/qga/channel-posix.c
index bf32158..579891d 100644
--- a/qga/channel-posix.c
+++ b/qga/channel-posix.c
@@ -61,7 +61,6 @@ static void ga_channel_listen_add(GAChannel *c, int listen_fd, bool create)
 
 static void ga_channel_listen_close(GAChannel *c)
 {
-    g_assert(c->method == GA_CHANNEL_UNIX_LISTEN);
     g_assert(c->listen_channel);
     g_io_channel_shutdown(c->listen_channel, true, NULL);
     g_io_channel_unref(c->listen_channel);
@@ -77,7 +76,7 @@ static void ga_channel_client_close(GAChannel *c)
     g_io_channel_shutdown(c->client_channel, true, NULL);
     g_io_channel_unref(c->client_channel);
     c->client_channel = NULL;
-    if (c->method == GA_CHANNEL_UNIX_LISTEN && c->listen_channel) {
+    if (c->listen_channel) {
         ga_channel_listen_add(c, 0, false);
     }
 }
@@ -255,8 +254,7 @@ GAChannel *ga_channel_new(GAChannelMethod method, const gchar *path,
 
 void ga_channel_free(GAChannel *c)
 {
-    if (c->method == GA_CHANNEL_UNIX_LISTEN
-        && c->listen_channel) {
+    if (c->listen_channel) {
         ga_channel_listen_close(c);
     }
     if (c->client_channel) {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PULL for-2.8 4/5] sockets: add AF_VSOCK support
  2016-11-01  0:59 [Qemu-devel] [PULL for-2.8 0/5] qemu-ga patch queue for 2.8 Michael Roth
                   ` (2 preceding siblings ...)
  2016-11-01  0:59 ` [Qemu-devel] [PULL for-2.8 3/5] qga: drop unnecessary GA_CHANNEL_UNIX_LISTEN checks Michael Roth
@ 2016-11-01  0:59 ` Michael Roth
  2016-11-01  0:59 ` [Qemu-devel] [PULL for-2.8 5/5] qga: add vsock-listen method Michael Roth
  2016-11-01 12:47 ` [Qemu-devel] [PULL for-2.8 0/5] qemu-ga patch queue for 2.8 Peter Maydell
  5 siblings, 0 replies; 7+ messages in thread
From: Michael Roth @ 2016-11-01  0:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Stefan Hajnoczi

From: Stefan Hajnoczi <stefanha@redhat.com>

Add the AF_VSOCK address family so that qemu-ga will be able to use
virtio-vsock.

The AF_VSOCK address family uses <cid, port> address tuples.  The cid is
the unique identifier comparable to an IP address.  AF_VSOCK does not
use name resolution so it's easy to convert between struct sockaddr_vm
and strings.

This patch defines a VsockSocketAddress instead of trying to piggy-back
on InetSocketAddress.  This is cleaner in the long run since it avoids
lots of IPv4 vs IPv6 vs vsock special casing.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
* treat trailing commas as garbage when parsing (Eric Blake)
* add configure check instead of checking AF_VSOCK directly
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 configure           |  31 +++++++
 qapi-schema.json    |  23 +++++-
 util/qemu-sockets.c | 227 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 280 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 6b7acb1..fd6f898 100755
--- a/configure
+++ b/configure
@@ -4674,6 +4674,33 @@ if compile_prog "" "" ; then
     have_rtnetlink=yes
 fi
 
+##########################################
+# check for usable AF_VSOCK environment
+have_af_vsock=no
+cat > $TMPC << EOF
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#if !defined(AF_VSOCK)
+# error missing AF_VSOCK flag
+#endif
+#include <linux/vm_sockets.h>
+int main(void) {
+    int sock, ret;
+    struct sockaddr_vm svm;
+    socklen_t len = sizeof(svm);
+    sock = socket(AF_VSOCK, SOCK_STREAM, 0);
+    ret = getpeername(sock, (struct sockaddr *)&svm, &len);
+    if ((ret == -1) && (errno == ENOTCONN)) {
+        return 0;
+    }
+    return -1;
+}
+EOF
+if compile_prog "" "" ; then
+    have_af_vsock=yes
+fi
+
 #################################################
 # Sparc implicitly links with --relax, which is
 # incompatible with -r, so --no-relax should be
@@ -5662,6 +5689,10 @@ if test "$replication" = "yes" ; then
   echo "CONFIG_REPLICATION=y" >> $config_host_mak
 fi
 
+if test "$have_af_vsock" = "yes" ; then
+  echo "CONFIG_AF_VSOCK=y" >> $config_host_mak
+fi
+
 # Hold two types of flag:
 #   CONFIG_THREAD_SETNAME_BYTHREAD  - we've got a way of setting the name on
 #                                     a thread we have a handle to
diff --git a/qapi-schema.json b/qapi-schema.json
index 8a7b527..5dc96af 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1063,12 +1063,14 @@
 #
 # @unix: unix socket
 #
+# @vsock: vsock family (since 2.8)
+#
 # @unknown: otherwise
 #
 # Since: 2.1
 ##
 { 'enum': 'NetworkAddressFamily',
-  'data': [ 'ipv4', 'ipv6', 'unix', 'unknown' ] }
+  'data': [ 'ipv4', 'ipv6', 'unix', 'vsock', 'unknown' ] }
 
 ##
 # @VncBasicInfo
@@ -3095,6 +3097,24 @@
     'path': 'str' } }
 
 ##
+# @VsockSocketAddress
+#
+# Captures a socket address in the vsock namespace.
+#
+# @cid: unique host identifier
+# @port: port
+#
+# Note that string types are used to allow for possible future hostname or
+# service resolution support.
+#
+# Since 2.8
+##
+{ 'struct': 'VsockSocketAddress',
+  'data': {
+    'cid': 'str',
+    'port': 'str' } }
+
+##
 # @SocketAddress
 #
 # Captures the address of a socket, which could also be a named file descriptor
@@ -3105,6 +3125,7 @@
   'data': {
     'inet': 'InetSocketAddress',
     'unix': 'UnixSocketAddress',
+    'vsock': 'VsockSocketAddress',
     'fd': 'String' } }
 
 ##
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 31f7fc6..fe1d07a 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -17,6 +17,10 @@
  */
 #include "qemu/osdep.h"
 
+#ifdef CONFIG_AF_VSOCK
+#include <linux/vm_sockets.h>
+#endif /* CONFIG_AF_VSOCK */
+
 #include "monitor/monitor.h"
 #include "qapi/error.h"
 #include "qemu/sockets.h"
@@ -75,6 +79,9 @@ NetworkAddressFamily inet_netfamily(int family)
     case PF_INET6: return NETWORK_ADDRESS_FAMILY_IPV6;
     case PF_INET:  return NETWORK_ADDRESS_FAMILY_IPV4;
     case PF_UNIX:  return NETWORK_ADDRESS_FAMILY_UNIX;
+#ifdef CONFIG_AF_VSOCK
+    case PF_VSOCK: return NETWORK_ADDRESS_FAMILY_VSOCK;
+#endif /* CONFIG_AF_VSOCK */
     }
     return NETWORK_ADDRESS_FAMILY_UNKNOWN;
 }
@@ -650,6 +657,181 @@ int inet_connect(const char *str, Error **errp)
     return sock;
 }
 
+#ifdef CONFIG_AF_VSOCK
+static bool vsock_parse_vaddr_to_sockaddr(const VsockSocketAddress *vaddr,
+                                          struct sockaddr_vm *svm,
+                                          Error **errp)
+{
+    unsigned long long val;
+
+    memset(svm, 0, sizeof(*svm));
+    svm->svm_family = AF_VSOCK;
+
+    if (parse_uint_full(vaddr->cid, &val, 10) < 0 ||
+        val > UINT32_MAX) {
+        error_setg(errp, "Failed to parse cid '%s'", vaddr->cid);
+        return false;
+    }
+    svm->svm_cid = val;
+
+    if (parse_uint_full(vaddr->port, &val, 10) < 0 ||
+        val > UINT32_MAX) {
+        error_setg(errp, "Failed to parse port '%s'", vaddr->port);
+        return false;
+    }
+    svm->svm_port = val;
+
+    return true;
+}
+
+static int vsock_connect_addr(const struct sockaddr_vm *svm, bool *in_progress,
+                              ConnectState *connect_state, Error **errp)
+{
+    int sock, rc;
+
+    *in_progress = false;
+
+    sock = qemu_socket(AF_VSOCK, SOCK_STREAM, 0);
+    if (sock < 0) {
+        error_setg_errno(errp, errno, "Failed to create socket");
+        return -1;
+    }
+    if (connect_state != NULL) {
+        qemu_set_nonblock(sock);
+    }
+    /* connect to peer */
+    do {
+        rc = 0;
+        if (connect(sock, (const struct sockaddr *)svm, sizeof(*svm)) < 0) {
+            rc = -errno;
+        }
+    } while (rc == -EINTR);
+
+    if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) {
+        connect_state->fd = sock;
+        qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state);
+        *in_progress = true;
+    } else if (rc < 0) {
+        error_setg_errno(errp, errno, "Failed to connect socket");
+        closesocket(sock);
+        return -1;
+    }
+    return sock;
+}
+
+static int vsock_connect_saddr(VsockSocketAddress *vaddr, Error **errp,
+                               NonBlockingConnectHandler *callback,
+                               void *opaque)
+{
+    struct sockaddr_vm svm;
+    int sock = -1;
+    bool in_progress;
+    ConnectState *connect_state = NULL;
+
+    if (!vsock_parse_vaddr_to_sockaddr(vaddr, &svm, errp)) {
+        return -1;
+    }
+
+    if (callback != NULL) {
+        connect_state = g_malloc0(sizeof(*connect_state));
+        connect_state->callback = callback;
+        connect_state->opaque = opaque;
+    }
+
+    sock = vsock_connect_addr(&svm, &in_progress, connect_state, errp);
+    if (sock < 0) {
+        /* do nothing */
+    } else if (in_progress) {
+        /* wait_for_connect() will do the rest */
+        return sock;
+    } else {
+        if (callback) {
+            callback(sock, NULL, opaque);
+        }
+    }
+    g_free(connect_state);
+    return sock;
+}
+
+static int vsock_listen_saddr(VsockSocketAddress *vaddr,
+                              Error **errp)
+{
+    struct sockaddr_vm svm;
+    int slisten;
+
+    if (!vsock_parse_vaddr_to_sockaddr(vaddr, &svm, errp)) {
+        return -1;
+    }
+
+    slisten = qemu_socket(AF_VSOCK, SOCK_STREAM, 0);
+    if (slisten < 0) {
+        error_setg_errno(errp, errno, "Failed to create socket");
+        return -1;
+    }
+
+    if (bind(slisten, (const struct sockaddr *)&svm, sizeof(svm)) != 0) {
+        error_setg_errno(errp, errno, "Failed to bind socket");
+        closesocket(slisten);
+        return -1;
+    }
+
+    if (listen(slisten, 1) != 0) {
+        error_setg_errno(errp, errno, "Failed to listen on socket");
+        closesocket(slisten);
+        return -1;
+    }
+    return slisten;
+}
+
+static VsockSocketAddress *vsock_parse(const char *str, Error **errp)
+{
+    VsockSocketAddress *addr = NULL;
+    char cid[33];
+    char port[33];
+    int n;
+
+    if (sscanf(str, "%32[^:]:%32[^,]%n", cid, port, &n) != 2) {
+        error_setg(errp, "error parsing address '%s'", str);
+        return NULL;
+    }
+    if (str[n] != '\0') {
+        error_setg(errp, "trailing characters in address '%s'", str);
+        return NULL;
+    }
+
+    addr = g_new0(VsockSocketAddress, 1);
+    addr->cid = g_strdup(cid);
+    addr->port = g_strdup(port);
+    return addr;
+}
+#else
+static void vsock_unsupported(Error **errp)
+{
+    error_setg(errp, "socket family AF_VSOCK unsupported");
+}
+
+static int vsock_connect_saddr(VsockSocketAddress *vaddr, Error **errp,
+                               NonBlockingConnectHandler *callback,
+                               void *opaque)
+{
+    vsock_unsupported(errp);
+    return -1;
+}
+
+static int vsock_listen_saddr(VsockSocketAddress *vaddr,
+                              Error **errp)
+{
+    vsock_unsupported(errp);
+    return -1;
+}
+
+static VsockSocketAddress *vsock_parse(const char *str, Error **errp)
+{
+    vsock_unsupported(errp);
+    return NULL;
+}
+#endif /* CONFIG_AF_VSOCK */
+
 #ifndef _WIN32
 
 static int unix_listen_saddr(UnixSocketAddress *saddr,
@@ -864,6 +1046,12 @@ SocketAddress *socket_parse(const char *str, Error **errp)
             addr->u.fd.data = g_new(String, 1);
             addr->u.fd.data->str = g_strdup(str + 3);
         }
+    } else if (strstart(str, "vsock:", NULL)) {
+        addr->type = SOCKET_ADDRESS_KIND_VSOCK;
+        addr->u.vsock.data = vsock_parse(str + strlen("vsock:"), errp);
+        if (addr->u.vsock.data == NULL) {
+            goto fail;
+        }
     } else {
         addr->type = SOCKET_ADDRESS_KIND_INET;
         addr->u.inet.data = inet_parse(str, errp);
@@ -900,6 +1088,10 @@ int socket_connect(SocketAddress *addr, Error **errp,
         }
         break;
 
+    case SOCKET_ADDRESS_KIND_VSOCK:
+        fd = vsock_connect_saddr(addr->u.vsock.data, errp, callback, opaque);
+        break;
+
     default:
         abort();
     }
@@ -923,6 +1115,10 @@ int socket_listen(SocketAddress *addr, Error **errp)
         fd = monitor_get_fd(cur_mon, addr->u.fd.data->str, errp);
         break;
 
+    case SOCKET_ADDRESS_KIND_VSOCK:
+        fd = vsock_listen_saddr(addr->u.vsock.data, errp);
+        break;
+
     default:
         abort();
     }
@@ -1022,6 +1218,26 @@ socket_sockaddr_to_address_unix(struct sockaddr_storage *sa,
 }
 #endif /* WIN32 */
 
+#ifdef CONFIG_AF_VSOCK
+static SocketAddress *
+socket_sockaddr_to_address_vsock(struct sockaddr_storage *sa,
+                                 socklen_t salen,
+                                 Error **errp)
+{
+    SocketAddress *addr;
+    VsockSocketAddress *vaddr;
+    struct sockaddr_vm *svm = (struct sockaddr_vm *)sa;
+
+    addr = g_new0(SocketAddress, 1);
+    addr->type = SOCKET_ADDRESS_KIND_VSOCK;
+    addr->u.vsock.data = vaddr = g_new0(VsockSocketAddress, 1);
+    vaddr->cid = g_strdup_printf("%u", svm->svm_cid);
+    vaddr->port = g_strdup_printf("%u", svm->svm_port);
+
+    return addr;
+}
+#endif /* CONFIG_AF_VSOCK */
+
 SocketAddress *
 socket_sockaddr_to_address(struct sockaddr_storage *sa,
                            socklen_t salen,
@@ -1037,6 +1253,11 @@ socket_sockaddr_to_address(struct sockaddr_storage *sa,
         return socket_sockaddr_to_address_unix(sa, salen, errp);
 #endif /* WIN32 */
 
+#ifdef CONFIG_AF_VSOCK
+    case AF_VSOCK:
+        return socket_sockaddr_to_address_vsock(sa, salen, errp);
+#endif
+
     default:
         error_setg(errp, "socket family %d unsupported",
                    sa->ss_family);
@@ -1103,6 +1324,12 @@ char *socket_address_to_string(struct SocketAddress *addr, Error **errp)
         buf = g_strdup(addr->u.fd.data->str);
         break;
 
+    case SOCKET_ADDRESS_KIND_VSOCK:
+        buf = g_strdup_printf("%s:%s",
+                              addr->u.vsock.data->cid,
+                              addr->u.vsock.data->port);
+        break;
+
     default:
         error_setg(errp, "socket family %d unsupported",
                    addr->type);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PULL for-2.8 5/5] qga: add vsock-listen method
  2016-11-01  0:59 [Qemu-devel] [PULL for-2.8 0/5] qemu-ga patch queue for 2.8 Michael Roth
                   ` (3 preceding siblings ...)
  2016-11-01  0:59 ` [Qemu-devel] [PULL for-2.8 4/5] sockets: add AF_VSOCK support Michael Roth
@ 2016-11-01  0:59 ` Michael Roth
  2016-11-01 12:47 ` [Qemu-devel] [PULL for-2.8 0/5] qemu-ga patch queue for 2.8 Peter Maydell
  5 siblings, 0 replies; 7+ messages in thread
From: Michael Roth @ 2016-11-01  0:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, Stefan Hajnoczi

From: Stefan Hajnoczi <stefanha@redhat.com>

Add AF_VSOCK (virtio-vsock) support as an alternative to virtio-serial.

  $ qemu-system-x86_64 -device vhost-vsock-pci,guest-cid=3 ...
  (guest)# qemu-ga -m vsock-listen -p 3:1234

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 qga/channel-posix.c | 25 +++++++++++++++++++++++++
 qga/channel.h       |  1 +
 qga/main.c          |  6 ++++--
 3 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/qga/channel-posix.c b/qga/channel-posix.c
index 579891d..71582e0 100644
--- a/qga/channel-posix.c
+++ b/qga/channel-posix.c
@@ -193,6 +193,31 @@ static gboolean ga_channel_open(GAChannel *c, const gchar *path, GAChannelMethod
         ga_channel_listen_add(c, fd, true);
         break;
     }
+    case GA_CHANNEL_VSOCK_LISTEN: {
+        Error *local_err = NULL;
+        SocketAddress *addr;
+        char *addr_str;
+        int fd;
+
+        addr_str = g_strdup_printf("vsock:%s", path);
+        addr = socket_parse(addr_str, &local_err);
+        g_free(addr_str);
+        if (local_err != NULL) {
+            g_critical("%s", error_get_pretty(local_err));
+            error_free(local_err);
+            return false;
+        }
+
+        fd = socket_listen(addr, &local_err);
+        qapi_free_SocketAddress(addr);
+        if (local_err != NULL) {
+            g_critical("%s", error_get_pretty(local_err));
+            error_free(local_err);
+            return false;
+        }
+        ga_channel_listen_add(c, fd, true);
+        break;
+    }
     default:
         g_critical("error binding/listening to specified socket");
         return false;
diff --git a/qga/channel.h b/qga/channel.h
index ae8cf0f..8fd0c8f 100644
--- a/qga/channel.h
+++ b/qga/channel.h
@@ -19,6 +19,7 @@ typedef enum {
     GA_CHANNEL_VIRTIO_SERIAL,
     GA_CHANNEL_ISA_SERIAL,
     GA_CHANNEL_UNIX_LISTEN,
+    GA_CHANNEL_VSOCK_LISTEN,
 } GAChannelMethod;
 
 typedef gboolean (*GAChannelCallback)(GIOCondition condition, gpointer opaque);
diff --git a/qga/main.c b/qga/main.c
index 0b9d04e..6caf215 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -190,8 +190,8 @@ static void usage(const char *cmd)
 "Usage: %s [-m <method> -p <path>] [<options>]\n"
 "QEMU Guest Agent %s\n"
 "\n"
-"  -m, --method      transport method: one of unix-listen, virtio-serial, or\n"
-"                    isa-serial (virtio-serial is the default)\n"
+"  -m, --method      transport method: one of unix-listen, virtio-serial,\n"
+"                    isa-serial, or vsock-listen (virtio-serial is the default)\n"
 "  -p, --path        device/socket path (the default for virtio-serial is:\n"
 "                    %s,\n"
 "                    the default for isa-serial is:\n"
@@ -659,6 +659,8 @@ static gboolean channel_init(GAState *s, const gchar *method, const gchar *path)
         channel_method = GA_CHANNEL_ISA_SERIAL;
     } else if (strcmp(method, "unix-listen") == 0) {
         channel_method = GA_CHANNEL_UNIX_LISTEN;
+    } else if (strcmp(method, "vsock-listen") == 0) {
+        channel_method = GA_CHANNEL_VSOCK_LISTEN;
     } else {
         g_critical("unsupported channel method/type: %s", method);
         return false;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PULL for-2.8 0/5] qemu-ga patch queue for 2.8
  2016-11-01  0:59 [Qemu-devel] [PULL for-2.8 0/5] qemu-ga patch queue for 2.8 Michael Roth
                   ` (4 preceding siblings ...)
  2016-11-01  0:59 ` [Qemu-devel] [PULL for-2.8 5/5] qga: add vsock-listen method Michael Roth
@ 2016-11-01 12:47 ` Peter Maydell
  5 siblings, 0 replies; 7+ messages in thread
From: Peter Maydell @ 2016-11-01 12:47 UTC (permalink / raw)
  To: Michael Roth; +Cc: QEMU Developers

On 1 November 2016 at 00:59, Michael Roth <mdroth@linux.vnet.ibm.com> wrote:
> The following changes since commit e80b4b8fb6babce7dcc91ea9ddeecbc351fd4646:
>
>   Merge remote-tracking branch 'remotes/awilliam/tags/vfio-updates-20161031.0' into staging (2016-10-31 18:19:06 +0000)
>
> are available in the git repository at:
>
>
>   git://github.com/mdroth/qemu.git tags/qga-pull-2016-10-31-tag
>
> for you to fetch changes up to 586ef5dee77180fc32e33bc08051600030630239:
>
>   qga: add vsock-listen method (2016-10-31 19:49:33 -0500)
>
> ----------------------------------------------------------------
> qemu-ga patch queue for 2.8
>
> * add guest-fstrim support for w32
> * add support for using virtio-vsock as the communication channel
>

Applied, thanks.

-- PMM

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-11-01 12:48 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-11-01  0:59 [Qemu-devel] [PULL for-2.8 0/5] qemu-ga patch queue for 2.8 Michael Roth
2016-11-01  0:59 ` [Qemu-devel] [PULL for-2.8 1/5] qga: minimal support for fstrim for Windows guests Michael Roth
2016-11-01  0:59 ` [Qemu-devel] [PULL for-2.8 2/5] qga: drop unused sockaddr in accept(2) call Michael Roth
2016-11-01  0:59 ` [Qemu-devel] [PULL for-2.8 3/5] qga: drop unnecessary GA_CHANNEL_UNIX_LISTEN checks Michael Roth
2016-11-01  0:59 ` [Qemu-devel] [PULL for-2.8 4/5] sockets: add AF_VSOCK support Michael Roth
2016-11-01  0:59 ` [Qemu-devel] [PULL for-2.8 5/5] qga: add vsock-listen method Michael Roth
2016-11-01 12:47 ` [Qemu-devel] [PULL for-2.8 0/5] qemu-ga patch queue for 2.8 Peter Maydell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).