If the hostname as returned by "gethostname" resolves to "localhost" (as it does with the broken Fedora-12 installer), then live migration will fail because the source will try to migrate to itself. Detect this situation up-front and abort the live migration before we do any real work. Signed-off-by: Chris Lalancette <clalance@xxxxxxxxxx> --- src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 2 +- src/util/util.c | 37 +++++++++++++++++++++++++++++++++++-- src/util/util.h | 1 + 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e3806cd..69ad686 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -568,6 +568,7 @@ virExecDaemonize; virSetCloseExec; virSetNonBlock; virFormatMacAddr; +virGetHostnameLocalhost; virGetHostname; virParseMacAddr; virFileDeletePid; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 0d8ec04..2123880 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7748,7 +7748,7 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn, if (port == QEMUD_MIGRATION_NUM_PORTS) port = 0; /* Get hostname */ - if ((hostname = virGetHostname(dconn)) == NULL) + if ((hostname = virGetHostnameLocalhost(0)) == NULL) goto cleanup; /* XXX this really should have been a properly well-formed diff --git a/src/util/util.c b/src/util/util.c index cdab300..72cc222 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -2193,11 +2193,11 @@ char *virIndexToDiskName(int idx, const char *prefix) #define AI_CANONIDN 0 #endif -char *virGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED) +char *virGetHostnameLocalhost(int allow_localhost) { int r; char hostname[HOST_NAME_MAX+1], *result; - struct addrinfo hints, *info; + struct addrinfo hints, *info, *res; r = gethostname (hostname, sizeof(hostname)); if (r == -1) { @@ -2217,6 +2217,34 @@ char *virGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED) hostname, gai_strerror(r)); return NULL; } + + /* if we aren't allowing localhost, then we iterate through the + * list and make sure none of the IPv4 addresses are 127.0.0.1 and + * that none of the IPv6 addresses are ::1 + */ + if (!allow_localhost) { + res = info; + while (res) { + if (res->ai_family == AF_INET) { + if (htonl(((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr) == INADDR_LOOPBACK) { + virUtilError(VIR_ERR_INTERNAL_ERROR, "%s", + _("canonical hostname pointed to localhost, but this is not allowed")); + freeaddrinfo(info); + return NULL; + } + } + else if (res->ai_family == AF_INET6) { + if (IN6_IS_ADDR_LOOPBACK(&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr)) { + virUtilError(VIR_ERR_INTERNAL_ERROR, "%s", + _("canonical hostname pointed to localhost, but this is not allowed")); + freeaddrinfo(info); + return NULL; + } + } + res = res->ai_next; + } + } + if (info->ai_canonname == NULL) { virUtilError(VIR_ERR_INTERNAL_ERROR, "%s", _("could not determine canonical host name")); @@ -2233,6 +2261,11 @@ char *virGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED) return result; } +char *virGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED) +{ + return virGetHostnameLocalhost(1); +} + /* send signal to a single process */ int virKillProcess(pid_t pid, int sig) { diff --git a/src/util/util.h b/src/util/util.h index 4207508..d024fe1 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -232,6 +232,7 @@ static inline int getuid (void) { return 0; } static inline int getgid (void) { return 0; } #endif +char *virGetHostnameLocalhost(int allow_localhost); char *virGetHostname(virConnectPtr conn); int virKillProcess(pid_t pid, int sig); -- 1.6.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list