From: Chris Lalancette Date: Fri, 19 Feb 2010 15:15:21 +0000 (+0100) Subject: Better error reporting for failed migration X-Git-Tag: v0.7.7~116 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b97c24b2e1eaea88fc9a62134097a5baf8a1f6b2;p=thirdparty%2Flibvirt.git Better error reporting for failed migration 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. * src/util/util.h src/util/util.c: add a new virGetHostnameLocalhost with an optional localhost check, and rewire virGetHostname() to use it * src/libvirt_private.syms: expose the new function * src/qemu/qemu_driver.c: use it in qemudDomainMigratePrepare2() --- diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b1de480ca1..185eb64662 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -565,6 +565,7 @@ virExecDaemonize; virSetCloseExec; virSetNonBlock; virFormatMacAddr; +virGetHostnameLocalhost; virGetHostname; virParseMacAddr; virFileDeletePid; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 98e8e4d033..1e4b49341f 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 c3b40844b1..1182729a24 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -2263,11 +2263,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) { @@ -2287,6 +2287,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")); @@ -2303,6 +2331,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 84601006dc..13bc39c7d6 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -233,6 +233,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);