Add API for issuing a 'migrate' monitor command for TCP

* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new API
  qemuMonitorMigrateToHost() for doing TCP migration
* src/qemu/qemu_driver.c: Convert to use qemuMonitorMigrateToHost().
  Also handle proper URIs (tcp:// as well as tcp:)
This commit is contained in:
Daniel P. Berrange 2009-09-23 14:48:49 +01:00
parent d7a3c8352e
commit 81f3edea8f
3 changed files with 77 additions and 23 deletions

View File

@ -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)

View File

@ -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;
}

View File

@ -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 */