On 10/09/2013 03:32 PM, Michal Privoznik wrote:
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_driver.c | 26 +++++++----
src/qemu/qemu_migration.c | 113 +++++++++++++++++++++++++++++++---------------
src/qemu/qemu_migration.h | 13 ++++--
3 files changed, 103 insertions(+), 49 deletions(-)
@@ -2260,31 +2254,66 @@ qemuMigrationPrepareAny(virQEMUDriverPtr
driver,
if (VIR_STRDUP(migrateFrom, "stdio") < 0)
goto cleanup;
} else {
+ virSocketAddr listenAddressSocket;
+ bool encloseAddress = false;
+ bool hostIPv6Capable = false;
+ bool qemuIPv6Capable = false;
virQEMUCapsPtr qemuCaps = NULL;
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;
+ }
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) {
+ if (virSocketAddrIsNumeric(listenAddress)) {
+ /* listenAddress is numeric IPv4 or IPv6 */
+ if (virSocketAddrParse(&listenAddressSocket, listenAddress,
AF_UNSPEC) < 0)
+ goto cleanup;
+
+ /* address parsed successfully */
+ 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;
+ }
+ }
+
+ /* IPv6 address must be enclosed in angle brackets on the cmd line */
+ encloseAddress = true;
This sets it for IPv4 as well. Also s/ angle// (and maybe 'escape' would be
better than 'enclose')
+ } else {
+ /* listenAddress is a hostname */
+ }
} else {
- listenAddr = "0.0.0.0";
+ /* Listen on :: instead of 0.0.0.0 if QEMU understands it
+ * and there is at least one IPv6 address configured
+ */
+ listenAddress = qemuIPv6Capable && hostIPv6Capable ?
+ encloseAddress = true, "::" : "0.0.0.0";
}
- virObjectUnref(qemuCaps);
- /* QEMU will be started with -incoming [::]:port
- * or -incoming 0.0.0.0:port
+ /* QEMU will be started with -incoming [<IPv6 addr>]:port,
+ * -incoming <IPv4 addr>:port or -incoming <hostname>:port
*/
- if (virAsprintf(&migrateFrom, "tcp:%s:%d", listenAddr, port) <
0)
+ if ((encloseAddress &&
+ virAsprintf(&migrateFrom, "tcp:[%s]:%d", listenAddress, port)
< 0) ||
+ (!encloseAddress &&
+ virAsprintf(&migrateFrom, "tcp:%s:%d", listenAddress, port)
< 0))
goto cleanup;
}
ACK with that fixed