Message ID | 1374891788-17567-1-git-send-email-mrhines@linux.vnet.ibm.com |
---|---|
State | New |
Headers | show |
Am 27.07.2013 04:23, schrieb mrhines@linux.vnet.ibm.com: > From: "Michael R. Hines" <mrhines@us.ibm.com> > > When testing with libvirt, a simple IPv6 migration test failed > because we were not using getaddrinfo() properly. > This makes IPv6 migration over RDMA work. > > Also, we forgot to turn the DPRINTF flag off =). > > Signed-off-by: Michael R. Hines <mrhines@us.ibm.com> > --- > migration-rdma.c | 35 ++++++++++++++++++++++------------- > 1 file changed, 22 insertions(+), 13 deletions(-) > > diff --git a/migration-rdma.c b/migration-rdma.c > index d044830..3256c9b 100644 > --- a/migration-rdma.c > +++ b/migration-rdma.c > @@ -27,7 +27,7 @@ > #include <string.h> > #include <rdma/rdma_cma.h> > > -#define DEBUG_RDMA > +//#define DEBUG_RDMA > //#define DEBUG_RDMA_VERBOSE > //#define DEBUG_RDMA_REALLY_VERBOSE > > @@ -392,6 +392,7 @@ typedef struct RDMAContext { > uint64_t unregistrations[RDMA_SIGNALED_SEND_MAX]; > > GHashTable *blockmap; > + bool ipv6; > } RDMAContext; > > /* > @@ -744,6 +745,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp) > char port_str[16]; > struct rdma_cm_event *cm_event; > char ip[40] = "unknown"; > + int af = rdma->ipv6 ? PF_INET6 : PF_INET; > > if (rdma->host == NULL || !strcmp(rdma->host, "")) { > ERROR(errp, "RDMA hostname has not been set\n"); > @@ -773,7 +775,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp) > goto err_resolve_get_addr; > } > > - inet_ntop(AF_INET, &((struct sockaddr_in *) res->ai_addr)->sin_addr, > + inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr, > ip, sizeof ip); > DPRINTF("%s => %s\n", rdma->host, ip); > > @@ -2236,9 +2238,12 @@ err_rdma_source_connect: > static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) > { > int ret = -EINVAL, idx; > + int af = rdma->ipv6 ? PF_INET6 : PF_INET; > struct sockaddr_in sin; > struct rdma_cm_id *listen_id; > char ip[40] = "unknown"; > + struct addrinfo *res; > + char port_str[16]; > > for (idx = 0; idx <= RDMA_WRID_MAX; idx++) { > rdma->wr_data[idx].control_len = 0; > @@ -2266,27 +2271,30 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) > } > > memset(&sin, 0, sizeof(sin)); > - sin.sin_family = AF_INET; > + sin.sin_family = af; > sin.sin_port = htons(rdma->port); > + snprintf(port_str, 16, "%d", rdma->port); > + port_str[15] = '\0'; > > if (rdma->host && strcmp("", rdma->host)) { > - struct hostent *dest_addr; > - dest_addr = gethostbyname(rdma->host); > - if (!dest_addr) { > - ERROR(errp, "migration could not gethostbyname!\n"); > - ret = -EINVAL; > + ret = getaddrinfo(rdma->host, port_str, NULL, &res); > + if (ret < 0) { > + ERROR(errp, "could not getaddrinfo address %s\n", rdma->host); > goto err_dest_init_bind_addr; > } > - memcpy(&sin.sin_addr.s_addr, dest_addr->h_addr, > - dest_addr->h_length); > - inet_ntop(AF_INET, dest_addr->h_addr, ip, sizeof ip); > + > + > + inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr, > + ip, sizeof ip); > } else { > - sin.sin_addr.s_addr = INADDR_ANY; > + ERROR(errp, "migration host and port not specified!\n"); Since ERROR() appears to be operating on errp, none of them should be adding a \n. Andreas > + ret = -EINVAL; > + goto err_dest_init_bind_addr; > } > > DPRINTF("%s => %s\n", rdma->host, ip); > > - ret = rdma_bind_addr(listen_id, (struct sockaddr *)&sin); > + ret = rdma_bind_addr(listen_id, res->ai_addr); > if (ret) { > ERROR(errp, "Error: could not rdma_bind_addr!\n"); > goto err_dest_init_bind_addr; > @@ -2321,6 +2329,7 @@ static void *qemu_rdma_data_init(const char *host_port, Error **errp) > if (addr != NULL) { > rdma->port = atoi(addr->port); > rdma->host = g_strdup(addr->host); > + rdma->ipv6 = addr->ipv6; > } else { > ERROR(errp, "bad RDMA migration address '%s'", host_port); > g_free(rdma); >
On 07/26/2013 10:30 PM, Andreas Färber wrote: > Am 27.07.2013 04:23, schrieb mrhines@linux.vnet.ibm.com: >> From: "Michael R. Hines" <mrhines@us.ibm.com> >> >> When testing with libvirt, a simple IPv6 migration test failed >> because we were not using getaddrinfo() properly. >> This makes IPv6 migration over RDMA work. >> >> Also, we forgot to turn the DPRINTF flag off =). >> >> Signed-off-by: Michael R. Hines <mrhines@us.ibm.com> >> --- >> migration-rdma.c | 35 ++++++++++++++++++++++------------- >> 1 file changed, 22 insertions(+), 13 deletions(-) >> >> diff --git a/migration-rdma.c b/migration-rdma.c >> index d044830..3256c9b 100644 >> --- a/migration-rdma.c >> +++ b/migration-rdma.c >> @@ -27,7 +27,7 @@ >> #include <string.h> >> #include <rdma/rdma_cma.h> >> >> -#define DEBUG_RDMA >> +//#define DEBUG_RDMA >> //#define DEBUG_RDMA_VERBOSE >> //#define DEBUG_RDMA_REALLY_VERBOSE >> >> @@ -392,6 +392,7 @@ typedef struct RDMAContext { >> uint64_t unregistrations[RDMA_SIGNALED_SEND_MAX]; >> >> GHashTable *blockmap; >> + bool ipv6; >> } RDMAContext; >> >> /* >> @@ -744,6 +745,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp) >> char port_str[16]; >> struct rdma_cm_event *cm_event; >> char ip[40] = "unknown"; >> + int af = rdma->ipv6 ? PF_INET6 : PF_INET; >> >> if (rdma->host == NULL || !strcmp(rdma->host, "")) { >> ERROR(errp, "RDMA hostname has not been set\n"); >> @@ -773,7 +775,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp) >> goto err_resolve_get_addr; >> } >> >> - inet_ntop(AF_INET, &((struct sockaddr_in *) res->ai_addr)->sin_addr, >> + inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr, >> ip, sizeof ip); >> DPRINTF("%s => %s\n", rdma->host, ip); >> >> @@ -2236,9 +2238,12 @@ err_rdma_source_connect: >> static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) >> { >> int ret = -EINVAL, idx; >> + int af = rdma->ipv6 ? PF_INET6 : PF_INET; >> struct sockaddr_in sin; >> struct rdma_cm_id *listen_id; >> char ip[40] = "unknown"; >> + struct addrinfo *res; >> + char port_str[16]; >> >> for (idx = 0; idx <= RDMA_WRID_MAX; idx++) { >> rdma->wr_data[idx].control_len = 0; >> @@ -2266,27 +2271,30 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) >> } >> >> memset(&sin, 0, sizeof(sin)); >> - sin.sin_family = AF_INET; >> + sin.sin_family = af; >> sin.sin_port = htons(rdma->port); >> + snprintf(port_str, 16, "%d", rdma->port); >> + port_str[15] = '\0'; >> >> if (rdma->host && strcmp("", rdma->host)) { >> - struct hostent *dest_addr; >> - dest_addr = gethostbyname(rdma->host); >> - if (!dest_addr) { >> - ERROR(errp, "migration could not gethostbyname!\n"); >> - ret = -EINVAL; >> + ret = getaddrinfo(rdma->host, port_str, NULL, &res); >> + if (ret < 0) { >> + ERROR(errp, "could not getaddrinfo address %s\n", rdma->host); >> goto err_dest_init_bind_addr; >> } >> - memcpy(&sin.sin_addr.s_addr, dest_addr->h_addr, >> - dest_addr->h_length); >> - inet_ntop(AF_INET, dest_addr->h_addr, ip, sizeof ip); >> + >> + >> + inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr, >> + ip, sizeof ip); >> } else { >> - sin.sin_addr.s_addr = INADDR_ANY; >> + ERROR(errp, "migration host and port not specified!\n"); > Since ERROR() appears to be operating on errp, none of them should be > adding a \n. > > Andreas Acknowledged. >> + ret = -EINVAL; >> + goto err_dest_init_bind_addr; >> } >> >> DPRINTF("%s => %s\n", rdma->host, ip); >> >> - ret = rdma_bind_addr(listen_id, (struct sockaddr *)&sin); >> + ret = rdma_bind_addr(listen_id, res->ai_addr); >> if (ret) { >> ERROR(errp, "Error: could not rdma_bind_addr!\n"); >> goto err_dest_init_bind_addr; >> @@ -2321,6 +2329,7 @@ static void *qemu_rdma_data_init(const char *host_port, Error **errp) >> if (addr != NULL) { >> rdma->port = atoi(addr->port); >> rdma->host = g_strdup(addr->host); >> + rdma->ipv6 = addr->ipv6; >> } else { >> ERROR(errp, "bad RDMA migration address '%s'", host_port); >> g_free(rdma); >> >
On 07/27/2013 05:23 AM, mrhines@linux.vnet.ibm.com wrote: > From: "Michael R. Hines" <mrhines@us.ibm.com> > > When testing with libvirt, a simple IPv6 migration test failed > because we were not using getaddrinfo() properly. > This makes IPv6 migration over RDMA work. > > Also, we forgot to turn the DPRINTF flag off =). > > Signed-off-by: Michael R. Hines <mrhines@us.ibm.com> > --- > migration-rdma.c | 35 ++++++++++++++++++++++------------- > 1 file changed, 22 insertions(+), 13 deletions(-) > > diff --git a/migration-rdma.c b/migration-rdma.c > index d044830..3256c9b 100644 > --- a/migration-rdma.c > +++ b/migration-rdma.c > @@ -27,7 +27,7 @@ > #include <string.h> > #include <rdma/rdma_cma.h> > > -#define DEBUG_RDMA > +//#define DEBUG_RDMA Can you put this in a separate patch? > //#define DEBUG_RDMA_VERBOSE > //#define DEBUG_RDMA_REALLY_VERBOSE > > @@ -392,6 +392,7 @@ typedef struct RDMAContext { > uint64_t unregistrations[RDMA_SIGNALED_SEND_MAX]; > > GHashTable *blockmap; > + bool ipv6; > } RDMAContext; > > /* > @@ -744,6 +745,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp) > char port_str[16]; > struct rdma_cm_event *cm_event; > char ip[40] = "unknown"; > + int af = rdma->ipv6 ? PF_INET6 : PF_INET; We have code that handles ipv6 in utils/qemu-sockets.c, it also handle host and port parsing please take a look at inet_parse_connect_opts. I think it can be reused here and for the destination. Regards, Orit > > if (rdma->host == NULL || !strcmp(rdma->host, "")) { > ERROR(errp, "RDMA hostname has not been set\n"); > @@ -773,7 +775,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp) > goto err_resolve_get_addr; > } > > - inet_ntop(AF_INET, &((struct sockaddr_in *) res->ai_addr)->sin_addr, > + inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr, > ip, sizeof ip); > DPRINTF("%s => %s\n", rdma->host, ip); > > @@ -2236,9 +2238,12 @@ err_rdma_source_connect: > static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) > { > int ret = -EINVAL, idx; > + int af = rdma->ipv6 ? PF_INET6 : PF_INET; > struct sockaddr_in sin; > struct rdma_cm_id *listen_id; > char ip[40] = "unknown"; > + struct addrinfo *res; > + char port_str[16]; > > for (idx = 0; idx <= RDMA_WRID_MAX; idx++) { > rdma->wr_data[idx].control_len = 0; > @@ -2266,27 +2271,30 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) > } > > memset(&sin, 0, sizeof(sin)); > - sin.sin_family = AF_INET; > + sin.sin_family = af; > sin.sin_port = htons(rdma->port); > + snprintf(port_str, 16, "%d", rdma->port); > + port_str[15] = '\0'; > > if (rdma->host && strcmp("", rdma->host)) { > - struct hostent *dest_addr; > - dest_addr = gethostbyname(rdma->host); > - if (!dest_addr) { > - ERROR(errp, "migration could not gethostbyname!\n"); > - ret = -EINVAL; > + ret = getaddrinfo(rdma->host, port_str, NULL, &res); > + if (ret < 0) { > + ERROR(errp, "could not getaddrinfo address %s\n", rdma->host); > goto err_dest_init_bind_addr; > } > - memcpy(&sin.sin_addr.s_addr, dest_addr->h_addr, > - dest_addr->h_length); > - inet_ntop(AF_INET, dest_addr->h_addr, ip, sizeof ip); > + > + > + inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr, > + ip, sizeof ip); > } else { > - sin.sin_addr.s_addr = INADDR_ANY; > + ERROR(errp, "migration host and port not specified!\n"); > + ret = -EINVAL; > + goto err_dest_init_bind_addr; > } > > DPRINTF("%s => %s\n", rdma->host, ip); > > - ret = rdma_bind_addr(listen_id, (struct sockaddr *)&sin); > + ret = rdma_bind_addr(listen_id, res->ai_addr); > if (ret) { > ERROR(errp, "Error: could not rdma_bind_addr!\n"); > goto err_dest_init_bind_addr; > @@ -2321,6 +2329,7 @@ static void *qemu_rdma_data_init(const char *host_port, Error **errp) > if (addr != NULL) { > rdma->port = atoi(addr->port); > rdma->host = g_strdup(addr->host); > + rdma->ipv6 = addr->ipv6; > } else { > ERROR(errp, "bad RDMA migration address '%s'", host_port); > g_free(rdma); >
On 07/30/2013 04:14 AM, Orit Wasserman wrote: > On 07/27/2013 05:23 AM, mrhines@linux.vnet.ibm.com wrote: >> From: "Michael R. Hines" <mrhines@us.ibm.com> >> >> When testing with libvirt, a simple IPv6 migration test failed >> because we were not using getaddrinfo() properly. >> This makes IPv6 migration over RDMA work. >> >> Also, we forgot to turn the DPRINTF flag off =). >> >> Signed-off-by: Michael R. Hines <mrhines@us.ibm.com> >> --- >> migration-rdma.c | 35 ++++++++++++++++++++++------------- >> 1 file changed, 22 insertions(+), 13 deletions(-) >> >> diff --git a/migration-rdma.c b/migration-rdma.c >> index d044830..3256c9b 100644 >> --- a/migration-rdma.c >> +++ b/migration-rdma.c >> @@ -27,7 +27,7 @@ >> #include <string.h> >> #include <rdma/rdma_cma.h> >> >> -#define DEBUG_RDMA >> +//#define DEBUG_RDMA > Can you put this in a separate patch? Acknowledged. >> //#define DEBUG_RDMA_VERBOSE >> //#define DEBUG_RDMA_REALLY_VERBOSE >> >> @@ -392,6 +392,7 @@ typedef struct RDMAContext { >> uint64_t unregistrations[RDMA_SIGNALED_SEND_MAX]; >> >> GHashTable *blockmap; >> + bool ipv6; >> } RDMAContext; >> >> /* >> @@ -744,6 +745,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp) >> char port_str[16]; >> struct rdma_cm_event *cm_event; >> char ip[40] = "unknown"; >> + int af = rdma->ipv6 ? PF_INET6 : PF_INET; > We have code that handles ipv6 in utils/qemu-sockets.c, it also handle host > and port parsing please take a look at inet_parse_connect_opts. > I think it can be reused here and for the destination. RDMA cannot use that function - it creates a socket and RDMA does not use sockets. RDMA is *already*, however, using inet_parse() which does exactly what you said. > Regards, > Orit >> >> if (rdma->host == NULL || !strcmp(rdma->host, "")) { >> ERROR(errp, "RDMA hostname has not been set\n"); >> @@ -773,7 +775,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp) >> goto err_resolve_get_addr; >> } >> >> - inet_ntop(AF_INET, &((struct sockaddr_in *) res->ai_addr)->sin_addr, >> + inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr, >> ip, sizeof ip); >> DPRINTF("%s => %s\n", rdma->host, ip); >> >> @@ -2236,9 +2238,12 @@ err_rdma_source_connect: >> static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) >> { >> int ret = -EINVAL, idx; >> + int af = rdma->ipv6 ? PF_INET6 : PF_INET; >> struct sockaddr_in sin; >> struct rdma_cm_id *listen_id; >> char ip[40] = "unknown"; >> + struct addrinfo *res; >> + char port_str[16]; >> >> for (idx = 0; idx <= RDMA_WRID_MAX; idx++) { >> rdma->wr_data[idx].control_len = 0; >> @@ -2266,27 +2271,30 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) >> } >> >> memset(&sin, 0, sizeof(sin)); >> - sin.sin_family = AF_INET; >> + sin.sin_family = af; >> sin.sin_port = htons(rdma->port); >> + snprintf(port_str, 16, "%d", rdma->port); >> + port_str[15] = '\0'; >> >> if (rdma->host && strcmp("", rdma->host)) { >> - struct hostent *dest_addr; >> - dest_addr = gethostbyname(rdma->host); >> - if (!dest_addr) { >> - ERROR(errp, "migration could not gethostbyname!\n"); >> - ret = -EINVAL; >> + ret = getaddrinfo(rdma->host, port_str, NULL, &res); >> + if (ret < 0) { >> + ERROR(errp, "could not getaddrinfo address %s\n", rdma->host); >> goto err_dest_init_bind_addr; >> } >> - memcpy(&sin.sin_addr.s_addr, dest_addr->h_addr, >> - dest_addr->h_length); >> - inet_ntop(AF_INET, dest_addr->h_addr, ip, sizeof ip); >> + >> + >> + inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr, >> + ip, sizeof ip); >> } else { >> - sin.sin_addr.s_addr = INADDR_ANY; >> + ERROR(errp, "migration host and port not specified!\n"); >> + ret = -EINVAL; >> + goto err_dest_init_bind_addr; >> } >> >> DPRINTF("%s => %s\n", rdma->host, ip); >> >> - ret = rdma_bind_addr(listen_id, (struct sockaddr *)&sin); >> + ret = rdma_bind_addr(listen_id, res->ai_addr); >> if (ret) { >> ERROR(errp, "Error: could not rdma_bind_addr!\n"); >> goto err_dest_init_bind_addr; >> @@ -2321,6 +2329,7 @@ static void *qemu_rdma_data_init(const char *host_port, Error **errp) >> if (addr != NULL) { >> rdma->port = atoi(addr->port); >> rdma->host = g_strdup(addr->host); >> + rdma->ipv6 = addr->ipv6; >> } else { >> ERROR(errp, "bad RDMA migration address '%s'", host_port); >> g_free(rdma); >>
On 07/30/2013 05:57 PM, Michael R. Hines wrote: > On 07/30/2013 04:14 AM, Orit Wasserman wrote: >> On 07/27/2013 05:23 AM, mrhines@linux.vnet.ibm.com wrote: >>> From: "Michael R. Hines" <mrhines@us.ibm.com> >>> >>> When testing with libvirt, a simple IPv6 migration test failed >>> because we were not using getaddrinfo() properly. >>> This makes IPv6 migration over RDMA work. >>> >>> Also, we forgot to turn the DPRINTF flag off =). >>> >>> Signed-off-by: Michael R. Hines <mrhines@us.ibm.com> >>> --- >>> migration-rdma.c | 35 ++++++++++++++++++++++------------- >>> 1 file changed, 22 insertions(+), 13 deletions(-) >>> >>> diff --git a/migration-rdma.c b/migration-rdma.c >>> index d044830..3256c9b 100644 >>> --- a/migration-rdma.c >>> +++ b/migration-rdma.c >>> @@ -27,7 +27,7 @@ >>> #include <string.h> >>> #include <rdma/rdma_cma.h> >>> -#define DEBUG_RDMA >>> +//#define DEBUG_RDMA >> Can you put this in a separate patch? > > Acknowledged. > >>> //#define DEBUG_RDMA_VERBOSE >>> //#define DEBUG_RDMA_REALLY_VERBOSE >>> @@ -392,6 +392,7 @@ typedef struct RDMAContext { >>> uint64_t unregistrations[RDMA_SIGNALED_SEND_MAX]; >>> GHashTable *blockmap; >>> + bool ipv6; >>> } RDMAContext; >>> /* >>> @@ -744,6 +745,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp) >>> char port_str[16]; >>> struct rdma_cm_event *cm_event; >>> char ip[40] = "unknown"; >>> + int af = rdma->ipv6 ? PF_INET6 : PF_INET; >> We have code that handles ipv6 in utils/qemu-sockets.c, it also handle host >> and port parsing please take a look at inet_parse_connect_opts. >> I think it can be reused here and for the destination. > > RDMA cannot use that function - it creates a socket and RDMA does not use sockets. > > RDMA is *already*, however, using inet_parse() which does exactly what you said. > You can update the function so it can be used for RDMA also. Orit >> Regards, >> Orit >>> if (rdma->host == NULL || !strcmp(rdma->host, "")) { >>> ERROR(errp, "RDMA hostname has not been set\n"); >>> @@ -773,7 +775,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp) >>> goto err_resolve_get_addr; >>> } >>> - inet_ntop(AF_INET, &((struct sockaddr_in *) res->ai_addr)->sin_addr, >>> + inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr, >>> ip, sizeof ip); >>> DPRINTF("%s => %s\n", rdma->host, ip); >>> @@ -2236,9 +2238,12 @@ err_rdma_source_connect: >>> static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) >>> { >>> int ret = -EINVAL, idx; >>> + int af = rdma->ipv6 ? PF_INET6 : PF_INET; >>> struct sockaddr_in sin; >>> struct rdma_cm_id *listen_id; >>> char ip[40] = "unknown"; >>> + struct addrinfo *res; >>> + char port_str[16]; >>> for (idx = 0; idx <= RDMA_WRID_MAX; idx++) { >>> rdma->wr_data[idx].control_len = 0; >>> @@ -2266,27 +2271,30 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) >>> } >>> memset(&sin, 0, sizeof(sin)); >>> - sin.sin_family = AF_INET; >>> + sin.sin_family = af; >>> sin.sin_port = htons(rdma->port); >>> + snprintf(port_str, 16, "%d", rdma->port); >>> + port_str[15] = '\0'; >>> if (rdma->host && strcmp("", rdma->host)) { >>> - struct hostent *dest_addr; >>> - dest_addr = gethostbyname(rdma->host); >>> - if (!dest_addr) { >>> - ERROR(errp, "migration could not gethostbyname!\n"); >>> - ret = -EINVAL; >>> + ret = getaddrinfo(rdma->host, port_str, NULL, &res); >>> + if (ret < 0) { >>> + ERROR(errp, "could not getaddrinfo address %s\n", rdma->host); >>> goto err_dest_init_bind_addr; >>> } >>> - memcpy(&sin.sin_addr.s_addr, dest_addr->h_addr, >>> - dest_addr->h_length); >>> - inet_ntop(AF_INET, dest_addr->h_addr, ip, sizeof ip); >>> + >>> + >>> + inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr, >>> + ip, sizeof ip); >>> } else { >>> - sin.sin_addr.s_addr = INADDR_ANY; >>> + ERROR(errp, "migration host and port not specified!\n"); >>> + ret = -EINVAL; >>> + goto err_dest_init_bind_addr; >>> } >>> DPRINTF("%s => %s\n", rdma->host, ip); >>> - ret = rdma_bind_addr(listen_id, (struct sockaddr *)&sin); >>> + ret = rdma_bind_addr(listen_id, res->ai_addr); >>> if (ret) { >>> ERROR(errp, "Error: could not rdma_bind_addr!\n"); >>> goto err_dest_init_bind_addr; >>> @@ -2321,6 +2329,7 @@ static void *qemu_rdma_data_init(const char *host_port, Error **errp) >>> if (addr != NULL) { >>> rdma->port = atoi(addr->port); >>> rdma->host = g_strdup(addr->host); >>> + rdma->ipv6 = addr->ipv6; >>> } else { >>> ERROR(errp, "bad RDMA migration address '%s'", host_port); >>> g_free(rdma); >>> >
On 07/30/2013 11:31 AM, Orit Wasserman wrote: > On 07/30/2013 05:57 PM, Michael R. Hines wrote: >> On 07/30/2013 04:14 AM, Orit Wasserman wrote: >>> On 07/27/2013 05:23 AM, mrhines@linux.vnet.ibm.com wrote: >>>> From: "Michael R. Hines" <mrhines@us.ibm.com> >>>> >>>> When testing with libvirt, a simple IPv6 migration test failed >>>> because we were not using getaddrinfo() properly. >>>> This makes IPv6 migration over RDMA work. >>>> >>>> Also, we forgot to turn the DPRINTF flag off =). >>>> >>>> Signed-off-by: Michael R. Hines <mrhines@us.ibm.com> >>>> --- >>>> migration-rdma.c | 35 ++++++++++++++++++++++------------- >>>> 1 file changed, 22 insertions(+), 13 deletions(-) >>>> >>>> diff --git a/migration-rdma.c b/migration-rdma.c >>>> index d044830..3256c9b 100644 >>>> --- a/migration-rdma.c >>>> +++ b/migration-rdma.c >>>> @@ -27,7 +27,7 @@ >>>> #include <string.h> >>>> #include <rdma/rdma_cma.h> >>>> -#define DEBUG_RDMA >>>> +//#define DEBUG_RDMA >>> Can you put this in a separate patch? >> Acknowledged. >> >>>> //#define DEBUG_RDMA_VERBOSE >>>> //#define DEBUG_RDMA_REALLY_VERBOSE >>>> @@ -392,6 +392,7 @@ typedef struct RDMAContext { >>>> uint64_t unregistrations[RDMA_SIGNALED_SEND_MAX]; >>>> GHashTable *blockmap; >>>> + bool ipv6; >>>> } RDMAContext; >>>> /* >>>> @@ -744,6 +745,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp) >>>> char port_str[16]; >>>> struct rdma_cm_event *cm_event; >>>> char ip[40] = "unknown"; >>>> + int af = rdma->ipv6 ? PF_INET6 : PF_INET; >>> We have code that handles ipv6 in utils/qemu-sockets.c, it also handle host >>> and port parsing please take a look at inet_parse_connect_opts. >>> I think it can be reused here and for the destination. >> RDMA cannot use that function - it creates a socket and RDMA does not use sockets. >> >> RDMA is *already*, however, using inet_parse() which does exactly what you said. >> > You can update the function so it can be used for RDMA also. The inet_parse() function does everything that we need - it already understands IPv6 without opening an actual socket. Any more than that would require CONFIG_RDMA to be conditionalized inside of the utils/ source code, and that seems like a lot of work for such a small reward. - Michael > Orit > >>> Regards, >>> Orit >>>> if (rdma->host == NULL || !strcmp(rdma->host, "")) { >>>> ERROR(errp, "RDMA hostname has not been set\n"); >>>> @@ -773,7 +775,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp) >>>> goto err_resolve_get_addr; >>>> } >>>> - inet_ntop(AF_INET, &((struct sockaddr_in *) res->ai_addr)->sin_addr, >>>> + inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr, >>>> ip, sizeof ip); >>>> DPRINTF("%s => %s\n", rdma->host, ip); >>>> @@ -2236,9 +2238,12 @@ err_rdma_source_connect: >>>> static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) >>>> { >>>> int ret = -EINVAL, idx; >>>> + int af = rdma->ipv6 ? PF_INET6 : PF_INET; >>>> struct sockaddr_in sin; >>>> struct rdma_cm_id *listen_id; >>>> char ip[40] = "unknown"; >>>> + struct addrinfo *res; >>>> + char port_str[16]; >>>> for (idx = 0; idx <= RDMA_WRID_MAX; idx++) { >>>> rdma->wr_data[idx].control_len = 0; >>>> @@ -2266,27 +2271,30 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) >>>> } >>>> memset(&sin, 0, sizeof(sin)); >>>> - sin.sin_family = AF_INET; >>>> + sin.sin_family = af; >>>> sin.sin_port = htons(rdma->port); >>>> + snprintf(port_str, 16, "%d", rdma->port); >>>> + port_str[15] = '\0'; >>>> if (rdma->host && strcmp("", rdma->host)) { >>>> - struct hostent *dest_addr; >>>> - dest_addr = gethostbyname(rdma->host); >>>> - if (!dest_addr) { >>>> - ERROR(errp, "migration could not gethostbyname!\n"); >>>> - ret = -EINVAL; >>>> + ret = getaddrinfo(rdma->host, port_str, NULL, &res); >>>> + if (ret < 0) { >>>> + ERROR(errp, "could not getaddrinfo address %s\n", rdma->host); >>>> goto err_dest_init_bind_addr; >>>> } >>>> - memcpy(&sin.sin_addr.s_addr, dest_addr->h_addr, >>>> - dest_addr->h_length); >>>> - inet_ntop(AF_INET, dest_addr->h_addr, ip, sizeof ip); >>>> + >>>> + >>>> + inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr, >>>> + ip, sizeof ip); >>>> } else { >>>> - sin.sin_addr.s_addr = INADDR_ANY; >>>> + ERROR(errp, "migration host and port not specified!\n"); >>>> + ret = -EINVAL; >>>> + goto err_dest_init_bind_addr; >>>> } >>>> DPRINTF("%s => %s\n", rdma->host, ip); >>>> - ret = rdma_bind_addr(listen_id, (struct sockaddr *)&sin); >>>> + ret = rdma_bind_addr(listen_id, res->ai_addr); >>>> if (ret) { >>>> ERROR(errp, "Error: could not rdma_bind_addr!\n"); >>>> goto err_dest_init_bind_addr; >>>> @@ -2321,6 +2329,7 @@ static void *qemu_rdma_data_init(const char *host_port, Error **errp) >>>> if (addr != NULL) { >>>> rdma->port = atoi(addr->port); >>>> rdma->host = g_strdup(addr->host); >>>> + rdma->ipv6 = addr->ipv6; >>>> } else { >>>> ERROR(errp, "bad RDMA migration address '%s'", host_port); >>>> g_free(rdma); >>>>
On 07/31/2013 04:39 PM, Michael R. Hines wrote: > On 07/30/2013 11:31 AM, Orit Wasserman wrote: >> On 07/30/2013 05:57 PM, Michael R. Hines wrote: >>> On 07/30/2013 04:14 AM, Orit Wasserman wrote: >>>> On 07/27/2013 05:23 AM, mrhines@linux.vnet.ibm.com wrote: >>>>> From: "Michael R. Hines" <mrhines@us.ibm.com> >>>>> >>>>> When testing with libvirt, a simple IPv6 migration test failed >>>>> because we were not using getaddrinfo() properly. >>>>> This makes IPv6 migration over RDMA work. >>>>> >>>>> Also, we forgot to turn the DPRINTF flag off =). >>>>> >>>>> Signed-off-by: Michael R. Hines <mrhines@us.ibm.com> >>>>> --- >>>>> migration-rdma.c | 35 ++++++++++++++++++++++------------- >>>>> 1 file changed, 22 insertions(+), 13 deletions(-) >>>>> >>>>> diff --git a/migration-rdma.c b/migration-rdma.c >>>>> index d044830..3256c9b 100644 >>>>> --- a/migration-rdma.c >>>>> +++ b/migration-rdma.c >>>>> @@ -27,7 +27,7 @@ >>>>> #include <string.h> >>>>> #include <rdma/rdma_cma.h> >>>>> -#define DEBUG_RDMA >>>>> +//#define DEBUG_RDMA >>>> Can you put this in a separate patch? >>> Acknowledged. >>> >>>>> //#define DEBUG_RDMA_VERBOSE >>>>> //#define DEBUG_RDMA_REALLY_VERBOSE >>>>> @@ -392,6 +392,7 @@ typedef struct RDMAContext { >>>>> uint64_t unregistrations[RDMA_SIGNALED_SEND_MAX]; >>>>> GHashTable *blockmap; >>>>> + bool ipv6; >>>>> } RDMAContext; >>>>> /* >>>>> @@ -744,6 +745,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp) >>>>> char port_str[16]; >>>>> struct rdma_cm_event *cm_event; >>>>> char ip[40] = "unknown"; >>>>> + int af = rdma->ipv6 ? PF_INET6 : PF_INET; >>>> We have code that handles ipv6 in utils/qemu-sockets.c, it also handle host >>>> and port parsing please take a look at inet_parse_connect_opts. >>>> I think it can be reused here and for the destination. >>> RDMA cannot use that function - it creates a socket and RDMA does not use sockets. >>> >>> RDMA is *already*, however, using inet_parse() which does exactly what you said. >>> >> You can update the function so it can be used for RDMA also. > > The inet_parse() function does everything that we need - > it already understands IPv6 without opening an actual socket. > > Any more than that would require CONFIG_RDMA to be > conditionalized inside of the utils/ source code, > and that seems like a lot of work for such a small reward. > Agreed, Orit > - Michael > >> Orit >> >>>> Regards, >>>> Orit >>>>> if (rdma->host == NULL || !strcmp(rdma->host, "")) { >>>>> ERROR(errp, "RDMA hostname has not been set\n"); >>>>> @@ -773,7 +775,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp) >>>>> goto err_resolve_get_addr; >>>>> } >>>>> - inet_ntop(AF_INET, &((struct sockaddr_in *) res->ai_addr)->sin_addr, >>>>> + inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr, >>>>> ip, sizeof ip); >>>>> DPRINTF("%s => %s\n", rdma->host, ip); >>>>> @@ -2236,9 +2238,12 @@ err_rdma_source_connect: >>>>> static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) >>>>> { >>>>> int ret = -EINVAL, idx; >>>>> + int af = rdma->ipv6 ? PF_INET6 : PF_INET; >>>>> struct sockaddr_in sin; >>>>> struct rdma_cm_id *listen_id; >>>>> char ip[40] = "unknown"; >>>>> + struct addrinfo *res; >>>>> + char port_str[16]; >>>>> for (idx = 0; idx <= RDMA_WRID_MAX; idx++) { >>>>> rdma->wr_data[idx].control_len = 0; >>>>> @@ -2266,27 +2271,30 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) >>>>> } >>>>> memset(&sin, 0, sizeof(sin)); >>>>> - sin.sin_family = AF_INET; >>>>> + sin.sin_family = af; >>>>> sin.sin_port = htons(rdma->port); >>>>> + snprintf(port_str, 16, "%d", rdma->port); >>>>> + port_str[15] = '\0'; >>>>> if (rdma->host && strcmp("", rdma->host)) { >>>>> - struct hostent *dest_addr; >>>>> - dest_addr = gethostbyname(rdma->host); >>>>> - if (!dest_addr) { >>>>> - ERROR(errp, "migration could not gethostbyname!\n"); >>>>> - ret = -EINVAL; >>>>> + ret = getaddrinfo(rdma->host, port_str, NULL, &res); >>>>> + if (ret < 0) { >>>>> + ERROR(errp, "could not getaddrinfo address %s\n", rdma->host); >>>>> goto err_dest_init_bind_addr; >>>>> } >>>>> - memcpy(&sin.sin_addr.s_addr, dest_addr->h_addr, >>>>> - dest_addr->h_length); >>>>> - inet_ntop(AF_INET, dest_addr->h_addr, ip, sizeof ip); >>>>> + >>>>> + >>>>> + inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr, >>>>> + ip, sizeof ip); >>>>> } else { >>>>> - sin.sin_addr.s_addr = INADDR_ANY; >>>>> + ERROR(errp, "migration host and port not specified!\n"); >>>>> + ret = -EINVAL; >>>>> + goto err_dest_init_bind_addr; >>>>> } >>>>> DPRINTF("%s => %s\n", rdma->host, ip); >>>>> - ret = rdma_bind_addr(listen_id, (struct sockaddr *)&sin); >>>>> + ret = rdma_bind_addr(listen_id, res->ai_addr); >>>>> if (ret) { >>>>> ERROR(errp, "Error: could not rdma_bind_addr!\n"); >>>>> goto err_dest_init_bind_addr; >>>>> @@ -2321,6 +2329,7 @@ static void *qemu_rdma_data_init(const char *host_port, Error **errp) >>>>> if (addr != NULL) { >>>>> rdma->port = atoi(addr->port); >>>>> rdma->host = g_strdup(addr->host); >>>>> + rdma->ipv6 = addr->ipv6; >>>>> } else { >>>>> ERROR(errp, "bad RDMA migration address '%s'", host_port); >>>>> g_free(rdma); >>>>> >
Applied. Thanks. Regards, Anthony Liguori
diff --git a/migration-rdma.c b/migration-rdma.c index d044830..3256c9b 100644 --- a/migration-rdma.c +++ b/migration-rdma.c @@ -27,7 +27,7 @@ #include <string.h> #include <rdma/rdma_cma.h> -#define DEBUG_RDMA +//#define DEBUG_RDMA //#define DEBUG_RDMA_VERBOSE //#define DEBUG_RDMA_REALLY_VERBOSE @@ -392,6 +392,7 @@ typedef struct RDMAContext { uint64_t unregistrations[RDMA_SIGNALED_SEND_MAX]; GHashTable *blockmap; + bool ipv6; } RDMAContext; /* @@ -744,6 +745,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp) char port_str[16]; struct rdma_cm_event *cm_event; char ip[40] = "unknown"; + int af = rdma->ipv6 ? PF_INET6 : PF_INET; if (rdma->host == NULL || !strcmp(rdma->host, "")) { ERROR(errp, "RDMA hostname has not been set\n"); @@ -773,7 +775,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp) goto err_resolve_get_addr; } - inet_ntop(AF_INET, &((struct sockaddr_in *) res->ai_addr)->sin_addr, + inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr, ip, sizeof ip); DPRINTF("%s => %s\n", rdma->host, ip); @@ -2236,9 +2238,12 @@ err_rdma_source_connect: static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) { int ret = -EINVAL, idx; + int af = rdma->ipv6 ? PF_INET6 : PF_INET; struct sockaddr_in sin; struct rdma_cm_id *listen_id; char ip[40] = "unknown"; + struct addrinfo *res; + char port_str[16]; for (idx = 0; idx <= RDMA_WRID_MAX; idx++) { rdma->wr_data[idx].control_len = 0; @@ -2266,27 +2271,30 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp) } memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; + sin.sin_family = af; sin.sin_port = htons(rdma->port); + snprintf(port_str, 16, "%d", rdma->port); + port_str[15] = '\0'; if (rdma->host && strcmp("", rdma->host)) { - struct hostent *dest_addr; - dest_addr = gethostbyname(rdma->host); - if (!dest_addr) { - ERROR(errp, "migration could not gethostbyname!\n"); - ret = -EINVAL; + ret = getaddrinfo(rdma->host, port_str, NULL, &res); + if (ret < 0) { + ERROR(errp, "could not getaddrinfo address %s\n", rdma->host); goto err_dest_init_bind_addr; } - memcpy(&sin.sin_addr.s_addr, dest_addr->h_addr, - dest_addr->h_length); - inet_ntop(AF_INET, dest_addr->h_addr, ip, sizeof ip); + + + inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr, + ip, sizeof ip); } else { - sin.sin_addr.s_addr = INADDR_ANY; + ERROR(errp, "migration host and port not specified!\n"); + ret = -EINVAL; + goto err_dest_init_bind_addr; } DPRINTF("%s => %s\n", rdma->host, ip); - ret = rdma_bind_addr(listen_id, (struct sockaddr *)&sin); + ret = rdma_bind_addr(listen_id, res->ai_addr); if (ret) { ERROR(errp, "Error: could not rdma_bind_addr!\n"); goto err_dest_init_bind_addr; @@ -2321,6 +2329,7 @@ static void *qemu_rdma_data_init(const char *host_port, Error **errp) if (addr != NULL) { rdma->port = atoi(addr->port); rdma->host = g_strdup(addr->host); + rdma->ipv6 = addr->ipv6; } else { ERROR(errp, "bad RDMA migration address '%s'", host_port); g_free(rdma);