From 4ec8f375cb1262717d6ee21eb0719ca166f1e9ff Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Wed, 6 Apr 2011 16:04:01 -0300 Subject: [RHEL6 qemu-kvm PATCH 2/2] Revert "Use getaddrinfo for migration" RH-Reverts: d59e05bf033eb557bbfb2fcf0352571ea4cb2ca0 RH-Reverts-patchwork-id: 20561 Bugzilla-related: 680356 Signed-off-by: Eduardo Habkost --- migration-tcp.c | 56 +++++++++++++++++++++------- net.c | 108 ------------------------------------------------------- qemu_socket.h | 3 -- 3 files changed, 42 insertions(+), 125 deletions(-) diff --git a/migration-tcp.c b/migration-tcp.c index a0bbb22..0de6c2e 100644 --- a/migration-tcp.c +++ b/migration-tcp.c @@ -49,6 +49,7 @@ static int tcp_close(FdMigrationState *s) return 0; } + static void tcp_wait_for_connect(void *opaque) { FdMigrationState *s = opaque; @@ -82,10 +83,13 @@ MigrationState *tcp_start_outgoing_migration(Monitor *mon, int blk, int inc) { + struct sockaddr_in addr; FdMigrationState *s; - int fd; int ret; + if (parse_host_port(&addr, host_port) < 0) + return NULL; + s = qemu_mallocz(sizeof(*s)); s->get_error = socket_errno; @@ -101,22 +105,35 @@ MigrationState *tcp_start_outgoing_migration(Monitor *mon, s->state = MIG_STATE_ACTIVE; s->mon = NULL; s->bandwidth_limit = bandwidth_limit; + s->fd = qemu_socket(PF_INET, SOCK_STREAM, 0); + if (s->fd == -1) { + qemu_free(s); + return NULL; + } + + socket_set_nonblock(s->fd); if (!detach) { migrate_fd_monitor_suspend(s, mon); } - ret = tcp_client_start(host_port, &fd); - s->fd = fd; - if (ret == -EINPROGRESS || ret == -EWOULDBLOCK) { - dprintf("connect in progress"); - qemu_set_fd_handler2(s->fd, NULL, NULL, tcp_wait_for_connect, s); - } else if (ret < 0) { + do { + ret = connect(s->fd, (struct sockaddr *)&addr, sizeof(addr)); + if (ret == -1) + ret = -(s->get_error(s)); + + if (ret == -EINPROGRESS || ret == -EWOULDBLOCK) + qemu_set_fd_handler2(s->fd, NULL, NULL, tcp_wait_for_connect, s); + } while (ret == -EINTR); + + if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK) { dprintf("connect failed\n"); - migrate_fd_error(s); - } else { + close(s->fd); + qemu_free(s); + return NULL; + } else if (ret >= 0) migrate_fd_connect(s); - } + return &s->mig_state; } @@ -155,14 +172,25 @@ out: int tcp_start_incoming_migration(const char *host_port) { - int ret; + struct sockaddr_in addr; + int val; int s; - ret = tcp_server_start(host_port, &s); - if (ret < 0) { - return ret; + if (parse_host_port(&addr, host_port) < 0) { + fprintf(stderr, "invalid host/port combination: %s\n", host_port); + return -EINVAL; } + s = qemu_socket(PF_INET, SOCK_STREAM, 0); + if (s == -1) + return -socket_error(); + + val = 1; + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val)); + + if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) + goto err; + if (listen(s, 1) == -1) goto err; diff --git a/net.c b/net.c index 9caacc7..2f498ae 100644 --- a/net.c +++ b/net.c @@ -134,114 +134,6 @@ fail: return -1; } -static int tcp_server_bind(int fd, struct addrinfo *rp) -{ - int ret; - int val = 1; - - /* allow fast reuse */ - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val)); - - ret = bind(fd, rp->ai_addr, rp->ai_addrlen); - - if (ret == -1) { - ret = -socket_error(); - } - return ret; - -} - -static int tcp_client_connect(int fd, struct addrinfo *rp) -{ - int ret; - - do { - ret = connect(fd, rp->ai_addr, rp->ai_addrlen); - if (ret == -1) { - ret = -socket_error(); - } - } while (ret == -EINTR); - - return ret; -} - - -static int tcp_start_common(const char *str, int *fd, bool server) -{ - char hostname[512]; - const char *service; - const char *name; - struct addrinfo hints; - struct addrinfo *result, *rp; - int s; - int sfd; - int ret = -EINVAL; - - *fd = -1; - service = str; - if (get_str_sep(hostname, sizeof(hostname), &service, ':') < 0) { - return -EINVAL; - } - if (server && strlen(hostname) == 0) { - name = NULL; - } else { - name = hostname; - } - - /* Obtain address(es) matching host/port */ - - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ - hints.ai_socktype = SOCK_STREAM; /* Datagram socket */ - - if (server) { - hints.ai_flags = AI_PASSIVE; - } - - s = getaddrinfo(name, service, &hints, &result); - if (s != 0) { - fprintf(stderr, "qemu: getaddrinfo: %s\n", gai_strerror(s)); - return -EINVAL; - } - - /* getaddrinfo() returns a list of address structures. - Try each address until we successfully bind/connect). - If socket(2) (or bind/connect(2)) fails, we (close the socket - and) try the next address. */ - - for (rp = result; rp != NULL; rp = rp->ai_next) { - sfd = qemu_socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - if (sfd == -1) { - ret = -errno; - continue; - } - socket_set_nonblock(sfd); - if (server) { - ret = tcp_server_bind(sfd, rp); - } else { - ret = tcp_client_connect(sfd, rp); - } - if (ret >= 0 || ret == -EINPROGRESS || ret == -EWOULDBLOCK) { - *fd = sfd; - break; /* Success */ - } - close(sfd); - } - - freeaddrinfo(result); - return ret; -} - -int tcp_server_start(const char *str, int *fd) -{ - return tcp_start_common(str, fd, true); -} - -int tcp_client_start(const char *str, int *fd) -{ - return tcp_start_common(str, fd, false); -} - int parse_host_port(struct sockaddr_in *saddr, const char *str) { char buf[512]; diff --git a/qemu_socket.h b/qemu_socket.h index 68a9e10..85168ea 100644 --- a/qemu_socket.h +++ b/qemu_socket.h @@ -57,7 +57,4 @@ int parse_host_src_port(struct sockaddr_in *haddr, struct sockaddr_in *saddr, const char *str); -int tcp_client_start(const char *str, int *fd); -int tcp_server_start(const char *str, int *fd); - #endif /* QEMU_SOCKET_H */ -- 1.7.3.2