[libvirt] [PATCH] qemu: enable direct migration over IPv6
Peter Krempa
pkrempa at redhat.com
Fri Feb 15 10:13:47 UTC 2013
On 02/15/13 11:00, Ján Tomko wrote:
> Use virURIParse in qemuMigrationPrepareDirect to allow parsing
> IPv6 addresses, which would cause an 'incorrect :port' error message
> before.
>
> To be able to migrate over IPv6, QEMU needs to listen on [::] instead
> of 0.0.0.0. This patch adds a call to getaddrinfo and sets the listen
> address based on the result.
>
> This will break migration if a hostname that can only be resolved on the
> source machine is passed in the migration URI, or if it does not resolve
> to the same address family on both sides.
>
> Bug: https://bugzilla.redhat.com/show_bug.cgi?id=846013
> ---
> src/qemu/qemu_migration.c | 65 +++++++++++++++++++++++++++++++++++++----------
> 1 file changed, 52 insertions(+), 13 deletions(-)
>
> diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
> index 36e55d2..c813c4a 100644
> --- a/src/qemu/qemu_migration.c
> +++ b/src/qemu/qemu_migration.c
> @@ -22,7 +22,10 @@
>
> #include <config.h>
>
> +#include <netdb.h>
> +#include <sys/socket.h>
> #include <sys/time.h>
> +#include <sys/types.h>
> #ifdef WITH_GNUTLS
> # include <gnutls/gnutls.h>
> # include <gnutls/x509.h>
> @@ -1835,8 +1838,11 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
> int this_port;
> char *hostname = NULL;
> char migrateFrom [64];
> - const char *p;
> + char *uri_str;
> int ret = -1;
> + bool ipv6 = false;
> + struct addrinfo *info;
> + virURIPtr uri;
>
> VIR_DEBUG("driver=%p, dconn=%p, cookiein=%s, cookieinlen=%d, "
> "cookieout=%p, cookieoutlen=%p, uri_in=%s, uri_out=%p, "
> @@ -1892,9 +1898,33 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
> goto cleanup;
> }
>
> - /* Get the port number. */
> - p = strrchr(uri_in, ':');
> - if (p == strchr(uri_in, ':')) {
> + /* Convert uri_in to well-formed URI with // after tcp: */
> + if (!(STRPREFIX(uri_in, "tcp://"))) {
> + if (virAsprintf(&uri_str, "tcp://%s",
> + uri_in + strlen("tcp:")) < 0) {
It might be better to use the STRSKIP macro instead here. That should
also check if the old "not entirely URI" is formatted well.
> + virReportOOMError();
> + goto cleanup;
> + }
> + }
> +
> + uri = virURIParse(uri_str ? uri_str : uri_in);
> + VIR_FREE(uri_str);
Possible uninitialized pointer free.
> +
> + if (uri == NULL) {
> + virReportError(VIR_ERR_INVALID_ARG, _("unable to parse URI: %s"),
> + uri_in);
> + goto cleanup;
> + }
> +
> + if (uri->server == NULL) {
> + virReportError(VIR_ERR_INVALID_ARG, _("missing host in migration"
> + " URI: %s"), uri_in);
> + goto cleanup;
> + } else {
> + hostname = uri->server;
> + }
> +
> + if (uri->port == 0) {
> /* Generate a port */
> this_port = QEMUD_MIGRATION_FIRST_PORT + port++;
> if (port == QEMUD_MIGRATION_NUM_PORTS)
> @@ -1907,21 +1937,30 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
> }
>
> } else {
> - p++; /* definitely has a ':' in it, see above */
> - this_port = virParseNumber(&p);
> - if (this_port == -1 || p-uri_in != strlen(uri_in)) {
> - virReportError(VIR_ERR_INVALID_ARG,
> - "%s", _("URI ended with incorrect ':port'"));
> - goto cleanup;
> - }
> + this_port = uri->port;
This cleans stuff up nicely.
> }
> }
>
> + if (getaddrinfo(hostname, NULL, NULL, &info)) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("unable to get address info for %s"), hostname);
> + goto cleanup;
Isn't there a possibility to fall back on IPv4 if this fails to minimize
the chance of regressing?
> + } else {
> + ipv6 = info->ai_family == AF_INET6;
> + }
> +
> if (*uri_out)
> VIR_DEBUG("Generated uri_out=%s", *uri_out);
>
> - /* QEMU will be started with -incoming tcp:0.0.0.0:port */
> - snprintf(migrateFrom, sizeof(migrateFrom), "tcp:0.0.0.0:%d", this_port);
> + /* QEMU will be started with -incoming tcp:0.0.0.0:port
> + * or -incoming tcp:[::]:port for IPv6 */
> + if (ipv6) {
> + snprintf(migrateFrom, sizeof(migrateFrom),
> + "tcp:[::]:%d", this_port);
> + } else {
> + snprintf(migrateFrom, sizeof(migrateFrom),
> + "tcp:0.0.0.0:%d", this_port);
I thing this would be doable. Just do IPv4 by default if the resolution
fails.
> + }
>
> ret = qemuMigrationPrepareAny(driver, dconn, cookiein, cookieinlen,
> cookieout, cookieoutlen, dname, dom_xml,
>
Peter
More information about the libvir-list
mailing list