[libvirt] [PATCH] qemu: fix default migration_address for NBD server

Michael Chapman mike at very.puzzling.org
Thu Dec 31 05:51:26 UTC 2015


If no migration_address is configured, QEMU will listen on 0.0.0.0 or
[::].  Commit 674afcb09e3d33500cfbbcf870ebf92cb99ecfa3 moved the
handling of this default value into a new qemuMigrationPrepareIncoming
function, however the address is also needed when starting the NBD
server from within qemuMigrationPrepareAny.

Without this commit, the nbd-server-start command fails if no explicit
migration_address is configured since libvirt passes a null value in the
listen address:

  {
    "execute": "nbd-server-start", "arguments": {
      "addr": {
        "type": "inet",
        "data": { "host": null, "port": "49153" }
      }
    },
    "id": "libvirt-14"
  }

The migration address only applies to direct migration. Unfortunately we
can't move this logic as far back as qemuMigrationPrepareDirect since
QEMU's IPv6 support is only known after it has been launched.

Signed-off-by: Michael Chapman <mike at very.puzzling.org>
---
 src/qemu/qemu_migration.c | 79 +++++++++++++++++++++++------------------------
 1 file changed, 38 insertions(+), 41 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 4519aef..3f83b57 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3307,54 +3307,14 @@ qemuMigrationPrepareIncoming(virDomainObjPtr vm,
         if (VIR_STRDUP(migrateFrom, "stdio") < 0)
             goto cleanup;
     } else {
-        bool encloseAddress = false;
-        bool hostIPv6Capable = false;
-        bool qemuIPv6Capable = false;
-        struct addrinfo *info = NULL;
-        struct addrinfo hints = { .ai_flags = AI_ADDRCONFIG,
-                                  .ai_socktype = SOCK_STREAM };
         const char *incFormat;
 
-        if (getaddrinfo("::", NULL, &hints, &info) == 0) {
-            freeaddrinfo(info);
-            hostIPv6Capable = true;
-        }
-        qemuIPv6Capable = virQEMUCapsGet(priv->qemuCaps,
-                                         QEMU_CAPS_IPV6_MIGRATION);
-
-        if (listenAddress) {
-            if (virSocketAddrNumericFamily(listenAddress) == 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;
-                }
-                /* IPv6 address must be escaped in brackets on the cmd line */
-                encloseAddress = true;
-            } else {
-                /* listenAddress is a hostname or IPv4 */
-            }
-        } else if (qemuIPv6Capable && hostIPv6Capable) {
-            /* Listen on :: instead of 0.0.0.0 if QEMU understands it
-             * and there is at least one IPv6 address configured
-             */
-            listenAddress = "::";
-            encloseAddress = true;
-        } else {
-            listenAddress = "0.0.0.0";
-        }
-
         /* QEMU will be started with
          *   -incoming protocol:[<IPv6 addr>]:port,
          *   -incoming protocol:<IPv4 addr>:port, or
          *   -incoming protocol:<hostname>:port
          */
-        if (encloseAddress)
+        if (virSocketAddrNumericFamily(listenAddress) == AF_INET6)
             incFormat = "%s:[%s]:%d";
         else
             incFormat = "%s:%s:%d";
@@ -3540,6 +3500,43 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
         goto stopjob;
     stopProcess = true;
 
+    if (!tunnel) {
+        bool hostIPv6Capable = false;
+        bool qemuIPv6Capable = false;
+        struct addrinfo *info = NULL;
+        struct addrinfo hints = { .ai_flags = AI_ADDRCONFIG,
+                                  .ai_socktype = SOCK_STREAM };
+
+        if (getaddrinfo("::", NULL, &hints, &info) == 0) {
+            freeaddrinfo(info);
+            hostIPv6Capable = true;
+        }
+        qemuIPv6Capable = virQEMUCapsGet(priv->qemuCaps,
+                                         QEMU_CAPS_IPV6_MIGRATION);
+
+        if (listenAddress) {
+            if (virSocketAddrNumericFamily(listenAddress) == AF_INET6) {
+                if (!qemuIPv6Capable) {
+                    virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+                                   _("qemu isn't capable of IPv6"));
+                    goto stopjob;
+                }
+                if (!hostIPv6Capable) {
+                    virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+                                   _("host isn't capable of IPv6"));
+                    goto stopjob;
+                }
+            }
+        } else if (qemuIPv6Capable && hostIPv6Capable) {
+            /* Listen on :: instead of 0.0.0.0 if QEMU understands it
+             * and there is at least one IPv6 address configured
+             */
+            listenAddress = "::";
+        } else {
+            listenAddress = "0.0.0.0";
+        }
+    }
+
     if (!(incoming = qemuMigrationPrepareIncoming(vm, tunnel, protocol,
                                                   listenAddress, port,
                                                   dataFD[0])))
-- 
2.4.3




More information about the libvir-list mailing list