]> xenbits.xensource.com Git - libvirt.git/commitdiff
Better error reporting for failed migration
authorChris Lalancette <clalance@redhat.com>
Fri, 19 Feb 2010 15:15:21 +0000 (16:15 +0100)
committerDaniel Veillard <veillard@redhat.com>
Fri, 19 Feb 2010 15:15:21 +0000 (16:15 +0100)
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()

src/libvirt_private.syms
src/qemu/qemu_driver.c
src/util/util.c
src/util/util.h

index b1de480ca168fd8008db831857a9552dc54c2882..185eb64662390d5dc8d87bc896bfc56daf69e2bd 100644 (file)
@@ -565,6 +565,7 @@ virExecDaemonize;
 virSetCloseExec;
 virSetNonBlock;
 virFormatMacAddr;
+virGetHostnameLocalhost;
 virGetHostname;
 virParseMacAddr;
 virFileDeletePid;
index 98e8e4d0335050704e7b77f42ecf76e175751cc7..1e4b49341f78cb1b490a2180ca9c9bf6b94c81b9 100644 (file)
@@ -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
index c3b40844b1430533d49d5270cbe4617496235449..1182729a2427e99a45cccbbc733cc6a9bb39889c 100644 (file)
@@ -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)
 {
index 84601006dcbadb2b46effd1f008042e942468fbe..13bc39c7d6715e263150a0f2ee08a4fba910c7b4 100644 (file)
@@ -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);