diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 7722e064cd..d8ba9d1ba6 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6493,12 +6493,10 @@ qemudDomainMigratePerform (virDomainPtr dom, struct qemud_driver *driver = dom->conn->privateData; virDomainObjPtr vm; virDomainEventPtr event = NULL; - char *safe_uri; - char cmd[HOST_NAME_MAX+50]; - char *info = NULL; int ret = -1; int paused = 0; int status; + xmlURIPtr uribits = NULL; unsigned long long transferred, remaining, total; qemuDriverLock(driver); @@ -6536,34 +6534,29 @@ qemudDomainMigratePerform (virDomainPtr dom, goto cleanup; /* Issue the migrate command. */ - safe_uri = qemudEscapeMonitorArg (uri); - if (!safe_uri) { - virReportOOMError (dom->conn); - goto cleanup; + if (STRPREFIX(uri, "tcp:") && !STRPREFIX(uri, "tcp://")) { + char *tmpuri; + if (virAsprintf(&tmpuri, "tcp://%s", uri + strlen("tcp:")) < 0) { + virReportOOMError(dom->conn); + goto cleanup; + } + uribits = xmlParseURI(tmpuri); + VIR_FREE(tmpuri); + } else { + uribits = xmlParseURI(uri); } - snprintf (cmd, sizeof cmd, "migrate \"%s\"", safe_uri); - VIR_FREE (safe_uri); - - if (qemudMonitorCommand (vm, cmd, &info) < 0) { - qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, - "%s", _("migrate operation failed")); + if (!uribits) { + qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR, + _("cannot parse URI %s"), uri); goto cleanup; } - DEBUG ("%s: migrate reply: %s", vm->def->name, info); - - /* Now check for "fail" in the output string */ - if (strstr(info, "fail") != NULL) { - qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, - _("migrate failed: %s"), info); + if (qemuMonitorMigrateToHost(vm, uribits->server, uribits->port) < 0) goto cleanup; - } /* it is also possible that the migrate didn't fail initially, but * rather failed later on. Check the output of "info migrate" */ - VIR_FREE(info); - if (qemuMonitorGetMigrationStatus(vm, &status, &transferred, &remaining, @@ -6607,7 +6600,8 @@ cleanup: VIR_DOMAIN_EVENT_RESUMED_MIGRATED); } - VIR_FREE(info); + if (uribits) + xmlFreeURI(uribits); if (vm) virDomainObjUnlock(vm); if (event) diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index fd137beec1..eadabc5faf 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -1088,3 +1088,59 @@ cleanup: VIR_FREE(reply); return ret; } + + +static int qemuMonitorMigrate(const virDomainObjPtr vm, + const char *dest) +{ + char *cmd = NULL; + char *info = NULL; + int ret = -1; + + if (virAsprintf(&cmd, "migrate %s", dest) < 0) { + virReportOOMError(NULL); + return -1; + } + + if (qemudMonitorCommand(vm, cmd, &info) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("unable to start migration to %s"), dest); + goto cleanup; + } + + DEBUG ("%s: migrate reply: %s", vm->def->name, info); + + /* Now check for "fail" in the output string */ + if (strstr(info, "fail") != NULL) { + qemudReportError (NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("migration to '%s' failed: %s"), dest, info); + goto cleanup; + } + + + ret = 0; + +cleanup: + VIR_FREE(info); + VIR_FREE(cmd); + return ret; +} + +int qemuMonitorMigrateToHost(const virDomainObjPtr vm, + const char *hostname, + int port) +{ + char *uri; + int ret; + + if (virAsprintf(&uri, "tcp:%s:%d", hostname, port) < 0) { + virReportOOMError(NULL); + return -1; + } + + ret = qemuMonitorMigrate(vm, uri); + + VIR_FREE(uri); + + return ret; +} diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h index cd6f1f1914..d6f8fd2d94 100644 --- a/src/qemu/qemu_monitor_text.h +++ b/src/qemu/qemu_monitor_text.h @@ -128,4 +128,8 @@ int qemuMonitorGetMigrationStatus(const virDomainObjPtr vm, unsigned long long *remaining, unsigned long long *total); +int qemuMonitorMigrateToHost(const virDomainObjPtr vm, + const char *hostname, + int port); + #endif /* QEMU_MONITOR_TEXT_H */