On Wed, Oct 09, 2013 at 01:02:14PM +0200, Michal Privoznik wrote: > Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> > --- > src/qemu/qemu_driver.c | 26 +++++++++---- > src/qemu/qemu_migration.c | 98 +++++++++++++++++++++++++++++++++-------------- > src/qemu/qemu_migration.h | 13 ++++--- > 3 files changed, 96 insertions(+), 41 deletions(-) > @@ -2260,31 +2260,61 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, > if (VIR_STRDUP(migrateFrom, "stdio") < 0) > goto cleanup; > } else { > + virSocketAddr listenAddressSocket; > + bool hostIPv6Capable = false; > + bool qemuIPv6Capable = false; > virQEMUCapsPtr qemuCaps = NULL; > struct addrinfo *info = NULL; > struct addrinfo hints = { .ai_flags = AI_ADDRCONFIG, > - .ai_socktype = SOCK_STREAM }; > + .ai_socktype = SOCK_STREAM }; > > + if (getaddrinfo("::", NULL, &hints, &info) == 0) { > + freeaddrinfo(info); > + hostIPv6Capable = true; > + } > if (!(qemuCaps = virQEMUCapsCacheLookupCopy(driver->qemuCapsCache, > (*def)->emulator))) > goto cleanup; > > - /* Listen on :: instead of 0.0.0.0 if QEMU understands it > - * and there is at least one IPv6 address configured > - */ > - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_IPV6_MIGRATION) && > - getaddrinfo("::", NULL, &hints, &info) == 0) { > - freeaddrinfo(info); > - listenAddr = "[::]"; > + qemuIPv6Capable = virQEMUCapsGet(qemuCaps, QEMU_CAPS_IPV6_MIGRATION); > + virObjectUnref(qemuCaps); > + > + if (listenAddress && > + virSocketAddrParse(&listenAddressSocket, listenAddress, AF_UNSPEC) > 0) { > + /* address parsed successfully */ > + > + if (virSocketAddrIsWildcard(&listenAddressSocket)) { > + /* user wants us to listen on 0.0.0.0 or :: */ > + > + if (VIR_SOCKET_ADDR_IS_FAMILY(&listenAddressSocket, AF_INET6)) { > + if (!qemuIPv6Capable) { > + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", > + _("qemu isn't capable of IPv6")); > + goto cleanup; > + } > + if (!hostIPv6Capable) { > + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", > + _("host isn't capable of IPv6")); > + goto cleanup; > + } > + listenAddress = "[::]"; > + } > + } > } else { > - listenAddr = "0.0.0.0"; > + /* Don't error out, the @listenAddress may be a hostname */ > + if (!listenAddress) { > + /* Listen on :: instead of 0.0.0.0 if QEMU understands it > + * and there is at least one IPv6 address configured > + */ > + listenAddress = qemuIPv6Capable && hostIPv6Capable ? > + "[::]" : "0.0.0.0"; > + } > } I think this if/else would be clearer as if (listenAddress) { if (virSocketAddrParse(&listenAddressSocket, listenAddress, AF_UNSPEC) < 0) { virResetLastError(); ... } else { .... } } else { listenAddress = qemuIPv6Capable && hostIPv6Capable ? "[::]" : "0.0.0.0"; } Though this still means we'll be polluting the logs with the errors if this is a hostname. So perhaps we need a method virSocketAddrIsNumeric(const char *addR) so we can skip the parse stage entirely without errors, if it is a hostname. 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 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list