diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 7aa0476fc3..3ca3f322a6 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1739,6 +1739,8 @@ qemuDomainMigrateGraphicsRelocate(virQEMUDriverPtr driver, qemuDomainObjPrivatePtr priv = vm->privateData; int ret; char *listenAddress; + virSocketAddr addr; + bool reformatted = false; if (!cookie) return 0; @@ -1753,10 +1755,24 @@ qemuDomainMigrateGraphicsRelocate(virQEMUDriverPtr driver, return 0; listenAddress = cookie->graphics->listen; + + /* Okay, here's the magic: some mgmt applications set bare '0' as listen + * address. On the other hand, it's a valid IPv4 address. This means, we + * need to reformat the address so the if statement below can check just + * for two ANYCAST addresses and not all their variants. */ + if (listenAddress && + virSocketAddrParse(&addr, listenAddress, AF_UNSPEC) > 0) { + listenAddress = virSocketAddrFormat(&addr); + reformatted = true; + } + if (!listenAddress || STREQ(listenAddress, "0.0.0.0") || - STREQ(listenAddress, "::")) + STREQ(listenAddress, "::")) { + if (reformatted) + VIR_FREE(listenAddress); listenAddress = cookie->remoteHostname; + } ret = qemuDomainObjEnterMonitorAsync(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT); diff --git a/tests/sockettest.c b/tests/sockettest.c index 156ef454c6..5b36a6c0bf 100644 --- a/tests/sockettest.c +++ b/tests/sockettest.c @@ -193,6 +193,20 @@ mymain(void) ret = -1; \ } while (0) +#define DO_TEST_PARSE_AND_CHECK_FORMAT(addrstr, addrformated, family, pass) \ + do { \ + virSocketAddr addr; \ + struct testParseData data = { &addr, addrstr, family, true}; \ + memset(&addr, 0, sizeof(addr)); \ + if (virtTestRun("Test parse " addrstr " family " #family, \ + 1, testParseHelper, &data) < 0) \ + ret = -1; \ + struct testFormatData data2 = { &addr, addrformated, pass }; \ + if (virtTestRun("Test format " addrstr " family " #family, \ + 1, testFormatHelper, &data2) < 0) \ + ret = -1; \ + } while (0) + #define DO_TEST_RANGE(saddr, eaddr, size, pass) \ do { \ struct testRangeData data = { saddr, eaddr, size, pass }; \ @@ -216,6 +230,16 @@ mymain(void) DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_UNIX, false); DO_TEST_PARSE_AND_FORMAT("127.0.0.256", AF_UNSPEC, false); + DO_TEST_PARSE_AND_CHECK_FORMAT("127.0.0.2", "127.0.0.2", AF_INET, true); + DO_TEST_PARSE_AND_CHECK_FORMAT("127.0.0.2", "127.0.0.3", AF_INET, false); + DO_TEST_PARSE_AND_CHECK_FORMAT("0", "0.0.0.0", AF_INET, true); + DO_TEST_PARSE_AND_CHECK_FORMAT("127", "0.0.0.127", AF_INET, true); + DO_TEST_PARSE_AND_CHECK_FORMAT("127", "127.0.0.0", AF_INET, false); + DO_TEST_PARSE_AND_CHECK_FORMAT("127.2", "127.0.0.2", AF_INET, true); + DO_TEST_PARSE_AND_CHECK_FORMAT("127.2", "127.2.0.0", AF_INET, false); + DO_TEST_PARSE_AND_CHECK_FORMAT("1.2.3", "1.2.0.3", AF_INET, true); + DO_TEST_PARSE_AND_CHECK_FORMAT("1.2.3", "1.2.3.0", AF_INET, false); + DO_TEST_PARSE_AND_FORMAT("::1", AF_UNSPEC, true); DO_TEST_PARSE_AND_FORMAT("::1", AF_INET, false); DO_TEST_PARSE_AND_FORMAT("::1", AF_INET6, true);