[libvirt] [PATCH] pass correct uri to source host when we do p2p migration

Wen Congyang wency at cn.fujitsu.com
Mon Jan 10 03:20:31 UTC 2011


When we migrate a guest from remote host to localhost by p2p, the libvirtd
on remote host will be deadlock. This patch fixes a bug and we can avoid
the deadlock with this patch.

The steps to reproduce this bug:
# virsh -c qemu+ssh://<remotehost IP>/system migrate --p2p <domain name> qemu+ssh:///system

We connect dest host(qemu+ssh:///system) on source host, and the uri we pass
to source host is qemu+ssh:///system. And then we connect a wrong dest host.

Signed-off-by: Wen Congyang <wency at cn.fujitsu.com>

---
 src/libvirt.c |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/src/libvirt.c b/src/libvirt.c
index ee2495a..81a1bf8 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -3533,22 +3533,71 @@ virDomainMigratePeer2Peer (virDomainPtr domain,
                            const char *uri,
                            unsigned long bandwidth)
 {
+    xmlURIPtr tempxmluri = NULL;
+    char * tempuri = NULL;
+    int ret = -1;
+    char * hostname = NULL;
+
     if (!domain->conn->driver->domainMigratePerform) {
         virLibConnError (domain->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
         virDispatchError(domain->conn);
         return -1;
     }
 
+    tempxmluri = xmlParseURI(uri);
+    if (!tempxmluri) {
+        virLibConnError (domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        virDispatchError(domain->conn);
+        goto out;
+    }
+    if (tempxmluri->server) {
+        tempuri = uri;
+    } else {
+        /* 
+         * The uri will be passed to source host. If user inputs qemu:///system,
+         * the dest host is localhost. But we connect the dest host on source
+         * host(a remote host). So we should pass qemu://<dest hostname>/system
+         * to the source host.
+         */
+        hostname = virGetHostname(NULL);
+        if (!hostname) {
+            virDispatchError(domain->conn);
+            goto out;
+        }
+
+        if (STRPREFIX(hostname, "localhost")) {
+            virLibConnError(domain->conn, VIR_ERR_INTERNAL_ERROR,
+                            _("hostname on destination resolved to localhost, but migration requires an FQDN"));
+            virDispatchError(domain->conn);
+            goto out;
+        }
+
+        tempxmluri->server = hostname;
+        tempuri = strdup((char *)xmlSaveUri(tempxmluri));
+        if (!tempuri) {
+            virReportOOMError();
+            virDispatchError(domain->conn);
+            goto out;
+        }
+    }
+
     /* Perform the migration.  The driver isn't supposed to return
      * until the migration is complete.
      */
-    return domain->conn->driver->domainMigratePerform(domain,
+    ret = domain->conn->driver->domainMigratePerform(domain,
                                                       NULL, /* cookie */
                                                       0,    /* cookielen */
-                                                      uri,
+                                                      tempuri,
                                                       flags,
                                                       dname,
                                                       bandwidth);
+
+out:
+    VIR_FREE(hostname);
+    if (tempuri && tempuri != uri)
+        VIR_FREE(tempuri);
+
+    return ret;
 }
 
 
-- 
1.7.1




More information about the libvir-list mailing list