On 04/20/2012 07:43 AM, Amos Kong wrote: > Use help functions in qemu-socket.c for tcp migration, > which already support ipv6 addresses. > > Currently errp will be set to UNDEFINED_ERROR when migration fails, > qemu would output "migration failed: ...", and current user can > see a message("An undefined error has occurred") in monitor. > > This patch changed tcp_start_outgoing_migration()/inet_connect() > /inet_connect_opts(), socket error would be passed back, > then current user can see a meaningful err message in monitor. > > Qemu will exit if listening fails, so output socket error > to qemu stderr. > > For IPv6 brackets must be mandatory if you require a port. > Referencing to RFC5952, the recommended format is: > [2312::8274]:5200 > > test status: Successed > listen side: qemu-kvm .... -incoming tcp:[2312::8274]:5200 > client side: qemu-kvm ... > (qemu) migrate -d tcp:[2312::8274]:5200 > > --- > Changes from v7: > - add unknown error process > > Signed-off-by: Amos Kong <ak...@redhat.com> > --- > migration-tcp.c | 77 > +++++++++++++++---------------------------------------- > migration.c | 14 ++++++---- > migration.h | 7 +++-- > vl.c | 6 ++++ > 4 files changed, 38 insertions(+), 66 deletions(-) > > diff --git a/migration-tcp.c b/migration-tcp.c > index 35a5781..440804d 100644 > --- a/migration-tcp.c > +++ b/migration-tcp.c > @@ -79,45 +79,32 @@ static void tcp_wait_for_connect(void *opaque) > } > } > > -int tcp_start_outgoing_migration(MigrationState *s, const char *host_port) > +int tcp_start_outgoing_migration(MigrationState *s, const char *host_port, > + Error **errp) > { > - struct sockaddr_in addr; > - int ret; > - > - ret = parse_host_port(&addr, host_port); > - if (ret < 0) { > - return ret; > - } > - > s->get_error = socket_errno; > s->write = socket_write; > s->close = tcp_close; > > - s->fd = qemu_socket(PF_INET, SOCK_STREAM, 0); > - if (s->fd == -1) { > - DPRINTF("Unable to open socket"); > - return -socket_error(); > - } > - > - socket_set_nonblock(s->fd); > - > - do { > - ret = connect(s->fd, (struct sockaddr *)&addr, sizeof(addr)); > - if (ret == -1) { > - ret = -socket_error(); > - } > - if (ret == -EINPROGRESS || ret == -EWOULDBLOCK) { > - qemu_set_fd_handler2(s->fd, NULL, NULL, tcp_wait_for_connect, s); > - return 0; > - } > - } while (ret == -EINTR); > + s->fd = inet_connect(host_port, false, errp); > > - if (ret < 0) { > + if (!error_is_set(errp)) { > + migrate_fd_connect(s); > + } else if (error_is_type(*errp, QERR_SOCKET_CONNECT_IN_PROGRESS)) { > + DPRINTF("connect in progress\n"); > + qemu_set_fd_handler2(s->fd, NULL, NULL, tcp_wait_for_connect, s); > + } else if (error_is_type(*errp, QERR_SOCKET_CREATE_FAILED)) { > + DPRINTF("connect failed\n"); > + return -1; > + } else if (error_is_type(*errp, QERR_SOCKET_CONNECT_FAILED)) { > DPRINTF("connect failed\n"); > migrate_fd_error(s); > - return ret; > + return -1; > + } else { > + DPRINTF("unknown error\n"); > + return -1; > } > - migrate_fd_connect(s); > + > return 0; > } > > @@ -155,40 +142,18 @@ out2: > close(s); > } > > -int tcp_start_incoming_migration(const char *host_port) > +int tcp_start_incoming_migration(const char *host_port, Error **errp) > { > - struct sockaddr_in addr; > - int val; > int s; > > - DPRINTF("Attempting to start an incoming migration\n"); > - > - 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)); > + s = inet_listen(host_port, NULL, 256, SOCK_STREAM, 0, errp); > > - if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) { > - goto err; > - } > - if (listen(s, 1) == -1) { > - goto err; > + if (s < 0) { > + return -1; > } > > qemu_set_fd_handler2(s, NULL, tcp_accept_incoming_migration, NULL, > (void *)(intptr_t)s); > > return 0; > - > -err: > - close(s); > - return -socket_error(); > } > diff --git a/migration.c b/migration.c > index 94f7839..6289bc7 100644 > --- a/migration.c > +++ b/migration.c > @@ -60,13 +60,13 @@ static MigrationState *migrate_get_current(void) > return ¤t_migration; > } > > -int qemu_start_incoming_migration(const char *uri) > +int qemu_start_incoming_migration(const char *uri, Error **errp) > { > const char *p; > int ret; > > if (strstart(uri, "tcp:", &p)) > - ret = tcp_start_incoming_migration(p); > + ret = tcp_start_incoming_migration(p, errp); > #if !defined(WIN32) > else if (strstart(uri, "exec:", &p)) > ret = exec_start_incoming_migration(p); > @@ -413,7 +413,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, > s = migrate_init(blk, inc); > > if (strstart(uri, "tcp:", &p)) { > - ret = tcp_start_outgoing_migration(s, p); > + ret = tcp_start_outgoing_migration(s, p, errp); > #if !defined(WIN32) > } else if (strstart(uri, "exec:", &p)) { > ret = exec_start_outgoing_migration(s, p); > @@ -428,9 +428,11 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, > } > > if (ret < 0) { > - DPRINTF("migration failed: %s\n", strerror(-ret)); > - /* FIXME: we should return meaningful errors */ > - error_set(errp, QERR_UNDEFINED_ERROR); > + if (!error_is_set(errp)) { > + DPRINTF("migration failed: %s\n", strerror(-ret)); > + /* FIXME: we should return meaningful errors */ > + error_set(errp, QERR_UNDEFINED_ERROR); > + } > return; > } > > diff --git a/migration.h b/migration.h > index 691b367..2e9ca2e 100644 > --- a/migration.h > +++ b/migration.h > @@ -37,7 +37,7 @@ struct MigrationState > > void process_incoming_migration(QEMUFile *f); > > -int qemu_start_incoming_migration(const char *uri); > +int qemu_start_incoming_migration(const char *uri, Error **errp); > > uint64_t migrate_max_downtime(void); > > @@ -49,9 +49,10 @@ int exec_start_incoming_migration(const char *host_port); > > int exec_start_outgoing_migration(MigrationState *s, const char *host_port); > > -int tcp_start_incoming_migration(const char *host_port); > +int tcp_start_incoming_migration(const char *host_port, Error **errp); > > -int tcp_start_outgoing_migration(MigrationState *s, const char *host_port); > +int tcp_start_outgoing_migration(MigrationState *s, const char *host_port, > + Error **errp); > > int unix_start_incoming_migration(const char *path); > > diff --git a/vl.c b/vl.c > index ae91a8a..c10dfc2 100644 > --- a/vl.c > +++ b/vl.c > @@ -3627,8 +3627,12 @@ int main(int argc, char **argv, char **envp) > } > > if (incoming) { > - int ret = qemu_start_incoming_migration(incoming); > + Error *errp = NULL; > + int ret = qemu_start_incoming_migration(incoming, &errp); > if (ret < 0) { > + if (error_is_set(&errp)) { > + fprintf(stderr, "Migrate: %s\n", error_get_pretty(errp)); > + } > fprintf(stderr, "Migration failed. Exit code %s(%d), exiting.\n", > incoming, ret); > exit(ret); >
Reviewed by: Orit Wasserman <owass...@redhat.com>