On Wed, Oct 09, 2013 at 01:02:14PM +0200, Michal Privoznik wrote:
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
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 :|