* [Qemu-devel] IPv6 support for TCP migrations
@ 2011-05-04 8:39 nick
2011-05-04 8:39 ` [Qemu-devel] [PATCH] migration-tcp: Allow incoming and outgoing migrations over IPv6 nick
2011-05-04 10:13 ` [Qemu-devel] IPv6 support for TCP migrations Daniel P. Berrange
0 siblings, 2 replies; 4+ messages in thread
From: nick @ 2011-05-04 8:39 UTC (permalink / raw)
To: qemu-devel; +Cc: nick
Hi,
Currently migration-tcp.c uses the IPv4-only socket functions, making
migrations over IPv6 impossible. Following is a tentative patch that switches
it to use inet_connect() and inet_listen().
However, the patch loses the non-blocking connect() behaviour seen with the
previous code. I'm not sure how much of an issue this is - if connect() blocks
here, does it block execution of the VM?
If so, I guess we need a non-blocking form of inet_connect(), or some way of
replicating the behaviour - it would potentially be needed for my NBD
reconnection patches too? I can see that a blocking connect() might not be an
issue while the KVM process is starting up, but could cause problems if we
try to reconnect while emulation is ongoing.
Thoughts?
/Nick
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH] migration-tcp: Allow incoming and outgoing migrations over IPv6
2011-05-04 8:39 [Qemu-devel] IPv6 support for TCP migrations nick
@ 2011-05-04 8:39 ` nick
2011-05-04 10:13 ` [Qemu-devel] IPv6 support for TCP migrations Daniel P. Berrange
1 sibling, 0 replies; 4+ messages in thread
From: nick @ 2011-05-04 8:39 UTC (permalink / raw)
To: qemu-devel; +Cc: nick, Nick Thomas
From: Nick Thomas <nick@bytemark.co.uk>
Signed-off-by: Nick Thomas <nick@bytemark.co.uk>
---
migration-tcp.c | 85 ++++++++-----------------------------------------------
1 files changed, 12 insertions(+), 73 deletions(-)
diff --git a/migration-tcp.c b/migration-tcp.c
index d3d80c9..8ae778e 100644
--- a/migration-tcp.c
+++ b/migration-tcp.c
@@ -48,46 +48,14 @@ static int tcp_close(FdMigrationState *s)
return 0;
}
-
-static void tcp_wait_for_connect(void *opaque)
-{
- FdMigrationState *s = opaque;
- int val, ret;
- socklen_t valsize = sizeof(val);
-
- DPRINTF("connect completed\n");
- do {
- ret = getsockopt(s->fd, SOL_SOCKET, SO_ERROR, (void *) &val, &valsize);
- } while (ret == -1 && (s->get_error(s)) == EINTR);
-
- if (ret < 0) {
- migrate_fd_error(s);
- return;
- }
-
- qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
-
- if (val == 0)
- migrate_fd_connect(s);
- else {
- DPRINTF("error connecting %d\n", val);
- migrate_fd_error(s);
- }
-}
-
MigrationState *tcp_start_outgoing_migration(Monitor *mon,
const char *host_port,
int64_t bandwidth_limit,
int detach,
- int blk,
- int inc)
+ int blk,
+ int inc)
{
- struct sockaddr_in addr;
FdMigrationState *s;
- int ret;
-
- if (parse_host_port(&addr, host_port) < 0)
- return NULL;
s = qemu_mallocz(sizeof(*s));
@@ -104,32 +72,20 @@ 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);
}
- 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);
+ s->fd = inet_connect(host_port, SOCK_STREAM);
- if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK) {
+ if (s->fd == -1) {
DPRINTF("connect failed\n");
migrate_fd_error(s);
- } else if (ret >= 0)
+ } else {
+ socket_set_nonblock(s->fd);
migrate_fd_connect(s);
+ }
return &s->mig_state;
}
@@ -170,34 +126,17 @@ out2:
int tcp_start_incoming_migration(const char *host_port)
{
- struct sockaddr_in addr;
- int val;
int s;
+ char *ostr = NULL;
- 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)
+ s = inet_listen(host_port, ostr, 0, 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;
+ }
qemu_set_fd_handler2(s, NULL, tcp_accept_incoming_migration, NULL,
(void *)(intptr_t)s);
return 0;
-
-err:
- close(s);
- return -socket_error();
}
+
--
1.7.0.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] IPv6 support for TCP migrations
2011-05-04 8:39 [Qemu-devel] IPv6 support for TCP migrations nick
2011-05-04 8:39 ` [Qemu-devel] [PATCH] migration-tcp: Allow incoming and outgoing migrations over IPv6 nick
@ 2011-05-04 10:13 ` Daniel P. Berrange
2011-05-04 10:50 ` Nicholas Thomas
1 sibling, 1 reply; 4+ messages in thread
From: Daniel P. Berrange @ 2011-05-04 10:13 UTC (permalink / raw)
To: nick; +Cc: nick, qemu-devel
On Wed, May 04, 2011 at 09:39:02AM +0100, nick@bytemark.co.uk wrote:
> Hi,
>
> Currently migration-tcp.c uses the IPv4-only socket functions, making
> migrations over IPv6 impossible. Following is a tentative patch that switches
> it to use inet_connect() and inet_listen().
>
> However, the patch loses the non-blocking connect() behaviour seen with the
> previous code. I'm not sure how much of an issue this is - if connect() blocks
> here, does it block execution of the VM?
>
> If so, I guess we need a non-blocking form of inet_connect(), or some way of
> replicating the behaviour - it would potentially be needed for my NBD
> reconnection patches too? I can see that a blocking connect() might not be an
> issue while the KVM process is starting up, but could cause problems if we
> try to reconnect while emulation is ongoing.
>
> Thoughts?
FWIW, Juan Quintela also posted a set of patches to add IPv6 support for
migration a few weeks back, but unfortunately they don't appear to have
been merged yet:
http://www.mail-archive.com/qemu-devel@nongnu.org/msg58954.html
IIUC, Juan's patches don't have the blocking connect() problem you
mention.
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] IPv6 support for TCP migrations
2011-05-04 10:13 ` [Qemu-devel] IPv6 support for TCP migrations Daniel P. Berrange
@ 2011-05-04 10:50 ` Nicholas Thomas
0 siblings, 0 replies; 4+ messages in thread
From: Nicholas Thomas @ 2011-05-04 10:50 UTC (permalink / raw)
To: Daniel P. Berrange; +Cc: qemu-devel, quintela
On Wed, 2011-05-04 at 11:13 +0100, Daniel P. Berrange wrote:
> On Wed, May 04, 2011 at 09:39:02AM +0100, nick@bytemark.co.uk wrote:
> > Hi,
> >
> > Currently migration-tcp.c uses the IPv4-only socket functions, making
> > migrations over IPv6 impossible. Following is a tentative patch that switches
> > it to use inet_connect() and inet_listen().
> >
> > However, the patch loses the non-blocking connect() behaviour seen with the
> > previous code. I'm not sure how much of an issue this is - if connect() blocks
> > here, does it block execution of the VM?
> >
> > If so, I guess we need a non-blocking form of inet_connect(), or some way of
> > replicating the behaviour - it would potentially be needed for my NBD
> > reconnection patches too? I can see that a blocking connect() might not be an
> > issue while the KVM process is starting up, but could cause problems if we
> > try to reconnect while emulation is ongoing.
> >
> > Thoughts?
>
> FWIW, Juan Quintela also posted a set of patches to add IPv6 support for
> migration a few weeks back, but unfortunately they don't appear to have
> been merged yet:
>
> http://www.mail-archive.com/qemu-devel@nongnu.org/msg58954.html
>
> IIUC, Juan's patches don't have the blocking connect() problem you
> mention.
Hi,
Those patches look closer than mine, yes, although I spotted a problem
in tcp_start_common() of that patch series (Juan CC'd):
> +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;
> + }
I think this will fail when specifying an IPv6 *address* and port, e.g:
migrate -d [::1]:5000
We already have code that does this correctly in qemu-sockets.c -
inet_parse() - which is primarily what I was trying to get the
benefit of, in my patch.
> +
> + /* 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;
> +}
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-05-04 10:50 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-04 8:39 [Qemu-devel] IPv6 support for TCP migrations nick
2011-05-04 8:39 ` [Qemu-devel] [PATCH] migration-tcp: Allow incoming and outgoing migrations over IPv6 nick
2011-05-04 10:13 ` [Qemu-devel] IPv6 support for TCP migrations Daniel P. Berrange
2011-05-04 10:50 ` Nicholas Thomas
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).