|
|
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 |
|