yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone
76daa3
From 8590cce4d4e18bd7fc02cbfa95931ff0c307b263 Mon Sep 17 00:00:00 2001
76daa3
From: Xiao Wang <jasowang@redhat.com>
76daa3
Date: Fri, 9 Jun 2017 05:31:03 +0200
76daa3
Subject: [PATCH 01/13] Revert "Change net/socket.c to use socket_*()
76daa3
 functions" again
76daa3
76daa3
RH-Author: Xiao Wang <jasowang@redhat.com>
76daa3
Message-id: <1496986263-5321-1-git-send-email-jasowang@redhat.com>
76daa3
Patchwork-id: 75543
76daa3
O-Subject: [RHEL7.4 qemu-kvm-rhev PATCH] Revert "Change net/socket.c to use socket_*() functions" again
76daa3
Bugzilla: 1451629
76daa3
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
76daa3
RH-Acked-by: David Hildenbrand <david@redhat.com>
76daa3
RH-Acked-by: Vlad Yasevich <vyasevic@redhat.com>
76daa3
RH-Acked-by: wexu@redhat.com
76daa3
76daa3
From: "Daniel P. Berrange" <berrange@redhat.com>
76daa3
76daa3
Bugzilla: 1451629
76daa3
Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=13387504
76daa3
Test status: Tested by QE and me
76daa3
Notes: conflict since we're lacking of 226799cec5fa ("socket: Make errp
76daa3
       the last parameter of socket_connect")
76daa3
76daa3
This reverts commit 883e4f7624e10b98d16d9adaffb8b1795664d899.
76daa3
76daa3
This code changed net/socket.c from using socket()+connect(),
76daa3
to using socket_connect(). In theory this is great, but in
76daa3
practice this has completely broken the ability to connect
76daa3
the frontend and backend:
76daa3
76daa3
  $ ./x86_64-softmmu/qemu-system-x86_64 \
76daa3
       -device e1000,id=e0,netdev=hn0,mac=DE:AD:BE:EF:AF:05 \
76daa3
       -netdev socket,id=hn0,connect=localhost:1234
76daa3
  qemu-system-x86_64: -device e1000,id=e0,netdev=hn0,mac=DE:AD:BE:EF:AF:05: Property 'e1000.netdev' can't find value 'hn0'
76daa3
76daa3
The old code would call net_socket_fd_init() synchronously,
76daa3
while letting the connect() complete in the backgorund. The
76daa3
new code moved net_socket_fd_init() so that it is only called
76daa3
after connect() completes in the background.
76daa3
76daa3
Thus at the time we initialize the NIC frontend, the backend
76daa3
does not exist.
76daa3
76daa3
The socket_connect() conversion as done is a bad fit for the
76daa3
current code, since it did not try to change the way it deals
76daa3
with async connection completion. Rather than try to fix this,
76daa3
just revert the socket_connect() conversion entirely.
76daa3
76daa3
The code is about to be converted to use QIOChannel which
76daa3
will let the problem be solved in a cleaner manner. This
76daa3
revert is more suitable for stable branches in the meantime.
76daa3
76daa3
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
76daa3
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
76daa3
Signed-off-by: Jason Wang <jasowang@redhat.com>
76daa3
(cherry picked from commit 6701e5514beab7b781a10424a94e9850c707287c)
76daa3
Signed-off-by: Jason Wang <jasowang@redhat.com>
76daa3
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
76daa3
76daa3
Conflicts:
76daa3
	net/socket.c
76daa3
---
76daa3
 net/socket.c | 127 ++++++++++++++++++++++++++---------------------------------
76daa3
 1 file changed, 56 insertions(+), 71 deletions(-)
76daa3
76daa3
diff --git a/net/socket.c b/net/socket.c
76daa3
index fe3547b..dcae1ae 100644
76daa3
--- a/net/socket.c
76daa3
+++ b/net/socket.c
76daa3
@@ -489,106 +489,91 @@ static int net_socket_listen_init(NetClientState *peer,
76daa3
 {
76daa3
     NetClientState *nc;
76daa3
     NetSocketState *s;
76daa3
-    SocketAddress *saddr;
76daa3
-    int ret;
76daa3
-    Error *local_error = NULL;
76daa3
+    struct sockaddr_in saddr;
76daa3
+    int fd, ret;
76daa3
 
76daa3
-    saddr = socket_parse(host_str, &local_error);
76daa3
-    if (saddr == NULL) {
76daa3
-        error_report_err(local_error);
76daa3
+    if (parse_host_port(&saddr, host_str) < 0)
76daa3
+        return -1;
76daa3
+
76daa3
+    fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
76daa3
+    if (fd < 0) {
76daa3
+        perror("socket");
76daa3
         return -1;
76daa3
     }
76daa3
+    qemu_set_nonblock(fd);
76daa3
+
76daa3
+    socket_set_fast_reuse(fd);
76daa3
 
76daa3
-    ret = socket_listen(saddr, &local_error);
76daa3
+    ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
76daa3
     if (ret < 0) {
76daa3
-        qapi_free_SocketAddress(saddr);
76daa3
-        error_report_err(local_error);
76daa3
+        perror("bind");
76daa3
+        closesocket(fd);
76daa3
+        return -1;
76daa3
+    }
76daa3
+    ret = listen(fd, 0);
76daa3
+    if (ret < 0) {
76daa3
+        perror("listen");
76daa3
+        closesocket(fd);
76daa3
         return -1;
76daa3
     }
76daa3
 
76daa3
     nc = qemu_new_net_client(&net_socket_info, peer, model, name);
76daa3
     s = DO_UPCAST(NetSocketState, nc, nc);
76daa3
     s->fd = -1;
76daa3
-    s->listen_fd = ret;
76daa3
+    s->listen_fd = fd;
76daa3
     s->nc.link_down = true;
76daa3
     net_socket_rs_init(&s->rs, net_socket_rs_finalize);
76daa3
 
76daa3
     qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
76daa3
-    qapi_free_SocketAddress(saddr);
76daa3
     return 0;
76daa3
 }
76daa3
 
76daa3
-typedef struct {
76daa3
-    NetClientState *peer;
76daa3
-    SocketAddress *saddr;
76daa3
-    char *model;
76daa3
-    char *name;
76daa3
-} socket_connect_data;
76daa3
-
76daa3
-static void socket_connect_data_free(socket_connect_data *c)
76daa3
-{
76daa3
-    qapi_free_SocketAddress(c->saddr);
76daa3
-    g_free(c->model);
76daa3
-    g_free(c->name);
76daa3
-    g_free(c);
76daa3
-}
76daa3
-
76daa3
-static void net_socket_connected(int fd, Error *err, void *opaque)
76daa3
-{
76daa3
-    socket_connect_data *c = opaque;
76daa3
-    NetSocketState *s;
76daa3
-    char *addr_str = NULL;
76daa3
-    Error *local_error = NULL;
76daa3
-
76daa3
-    addr_str = socket_address_to_string(c->saddr, &local_error);
76daa3
-    if (addr_str == NULL) {
76daa3
-        error_report_err(local_error);
76daa3
-        closesocket(fd);
76daa3
-        goto end;
76daa3
-    }
76daa3
-
76daa3
-    s = net_socket_fd_init(c->peer, c->model, c->name, fd, true);
76daa3
-    if (!s) {
76daa3
-        closesocket(fd);
76daa3
-        goto end;
76daa3
-    }
76daa3
-
76daa3
-    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
76daa3
-             "socket: connect to %s", addr_str);
76daa3
-
76daa3
-end:
76daa3
-    g_free(addr_str);
76daa3
-    socket_connect_data_free(c);
76daa3
-}
76daa3
-
76daa3
 static int net_socket_connect_init(NetClientState *peer,
76daa3
                                    const char *model,
76daa3
                                    const char *name,
76daa3
                                    const char *host_str)
76daa3
 {
76daa3
-    socket_connect_data *c = g_new0(socket_connect_data, 1);
76daa3
-    int fd = -1;
76daa3
-    Error *local_error = NULL;
76daa3
+    NetSocketState *s;
76daa3
+    int fd, connected, ret;
76daa3
+    struct sockaddr_in saddr;
76daa3
 
76daa3
-    c->peer = peer;
76daa3
-    c->model = g_strdup(model);
76daa3
-    c->name = g_strdup(name);
76daa3
-    c->saddr = socket_parse(host_str, &local_error);
76daa3
-    if (c->saddr == NULL) {
76daa3
-        goto err;
76daa3
-    }
76daa3
+    if (parse_host_port(&saddr, host_str) < 0)
76daa3
+        return -1;
76daa3
 
76daa3
-    fd = socket_connect(c->saddr, &local_error, net_socket_connected, c);
76daa3
+    fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
76daa3
     if (fd < 0) {
76daa3
-        goto err;
76daa3
+        perror("socket");
76daa3
+        return -1;
76daa3
     }
76daa3
+    qemu_set_nonblock(fd);
76daa3
 
76daa3
+    connected = 0;
76daa3
+    for(;;) {
76daa3
+        ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
76daa3
+        if (ret < 0) {
76daa3
+            if (errno == EINTR || errno == EWOULDBLOCK) {
76daa3
+                /* continue */
76daa3
+            } else if (errno == EINPROGRESS ||
76daa3
+                       errno == EALREADY ||
76daa3
+                       errno == EINVAL) {
76daa3
+                break;
76daa3
+            } else {
76daa3
+                perror("connect");
76daa3
+                closesocket(fd);
76daa3
+                return -1;
76daa3
+            }
76daa3
+        } else {
76daa3
+            connected = 1;
76daa3
+            break;
76daa3
+        }
76daa3
+    }
76daa3
+    s = net_socket_fd_init(peer, model, name, fd, connected);
76daa3
+    if (!s)
76daa3
+        return -1;
76daa3
+    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
76daa3
+             "socket: connect to %s:%d",
76daa3
+             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
76daa3
     return 0;
76daa3
-
76daa3
-err:
76daa3
-    error_report_err(local_error);
76daa3
-    socket_connect_data_free(c);
76daa3
-    return -1;
76daa3
 }
76daa3
 
76daa3
 static int net_socket_mcast_init(NetClientState *peer,
76daa3
-- 
76daa3
1.8.3.1
76daa3