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@xxxxxxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list