mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-23 21:15:20 +00:00
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:
parent
d7a3c8352e
commit
81f3edea8f
@ -6493,12 +6493,10 @@ qemudDomainMigratePerform (virDomainPtr dom,
|
|||||||
struct qemud_driver *driver = dom->conn->privateData;
|
struct qemud_driver *driver = dom->conn->privateData;
|
||||||
virDomainObjPtr vm;
|
virDomainObjPtr vm;
|
||||||
virDomainEventPtr event = NULL;
|
virDomainEventPtr event = NULL;
|
||||||
char *safe_uri;
|
|
||||||
char cmd[HOST_NAME_MAX+50];
|
|
||||||
char *info = NULL;
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
int paused = 0;
|
int paused = 0;
|
||||||
int status;
|
int status;
|
||||||
|
xmlURIPtr uribits = NULL;
|
||||||
unsigned long long transferred, remaining, total;
|
unsigned long long transferred, remaining, total;
|
||||||
|
|
||||||
qemuDriverLock(driver);
|
qemuDriverLock(driver);
|
||||||
@ -6536,34 +6534,29 @@ qemudDomainMigratePerform (virDomainPtr dom,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* Issue the migrate command. */
|
/* Issue the migrate command. */
|
||||||
safe_uri = qemudEscapeMonitorArg (uri);
|
if (STRPREFIX(uri, "tcp:") && !STRPREFIX(uri, "tcp://")) {
|
||||||
if (!safe_uri) {
|
char *tmpuri;
|
||||||
|
if (virAsprintf(&tmpuri, "tcp://%s", uri + strlen("tcp:")) < 0) {
|
||||||
virReportOOMError(dom->conn);
|
virReportOOMError(dom->conn);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
snprintf (cmd, sizeof cmd, "migrate \"%s\"", safe_uri);
|
uribits = xmlParseURI(tmpuri);
|
||||||
VIR_FREE (safe_uri);
|
VIR_FREE(tmpuri);
|
||||||
|
} else {
|
||||||
if (qemudMonitorCommand (vm, cmd, &info) < 0) {
|
uribits = xmlParseURI(uri);
|
||||||
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;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG ("%s: migrate reply: %s", vm->def->name, info);
|
if (qemuMonitorMigrateToHost(vm, uribits->server, uribits->port) < 0)
|
||||||
|
|
||||||
/* 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);
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
|
|
||||||
/* it is also possible that the migrate didn't fail initially, but
|
/* it is also possible that the migrate didn't fail initially, but
|
||||||
* rather failed later on. Check the output of "info migrate"
|
* rather failed later on. Check the output of "info migrate"
|
||||||
*/
|
*/
|
||||||
VIR_FREE(info);
|
|
||||||
|
|
||||||
if (qemuMonitorGetMigrationStatus(vm, &status,
|
if (qemuMonitorGetMigrationStatus(vm, &status,
|
||||||
&transferred,
|
&transferred,
|
||||||
&remaining,
|
&remaining,
|
||||||
@ -6607,7 +6600,8 @@ cleanup:
|
|||||||
VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
|
VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
VIR_FREE(info);
|
if (uribits)
|
||||||
|
xmlFreeURI(uribits);
|
||||||
if (vm)
|
if (vm)
|
||||||
virDomainObjUnlock(vm);
|
virDomainObjUnlock(vm);
|
||||||
if (event)
|
if (event)
|
||||||
|
@ -1088,3 +1088,59 @@ cleanup:
|
|||||||
VIR_FREE(reply);
|
VIR_FREE(reply);
|
||||||
return ret;
|
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;
|
||||||
|
}
|
||||||
|
@ -128,4 +128,8 @@ int qemuMonitorGetMigrationStatus(const virDomainObjPtr vm,
|
|||||||
unsigned long long *remaining,
|
unsigned long long *remaining,
|
||||||
unsigned long long *total);
|
unsigned long long *total);
|
||||||
|
|
||||||
|
int qemuMonitorMigrateToHost(const virDomainObjPtr vm,
|
||||||
|
const char *hostname,
|
||||||
|
int port);
|
||||||
|
|
||||||
#endif /* QEMU_MONITOR_TEXT_H */
|
#endif /* QEMU_MONITOR_TEXT_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user