mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-25 23:25:24 +00:00
Refactor native QEMU migration code
The code for tunnelled migration was added in a dedicated method, but the native migration code is still inline in the top level qemudDomainMigratePerform() API. Move the native code out into a dedicated method too to make things more maintainable. * src/qemu/qemu_driver.c: Pull code for performing a native QEMU migration out into separate method
This commit is contained in:
parent
543e013a15
commit
de85acdf3b
@ -6403,6 +6403,72 @@ cleanup:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Perform migration using QEMU's native TCP migrate support,
|
||||||
|
* not encrypted obviously
|
||||||
|
*/
|
||||||
|
static int doNativeMigrate(virDomainPtr dom,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
const char *uri,
|
||||||
|
unsigned long flags ATTRIBUTE_UNUSED,
|
||||||
|
const char *dname ATTRIBUTE_UNUSED,
|
||||||
|
unsigned long resource)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
xmlURIPtr uribits;
|
||||||
|
int status;
|
||||||
|
unsigned long long transferred, remaining, total;
|
||||||
|
|
||||||
|
/* Issue the migrate command. */
|
||||||
|
if (STRPREFIX(uri, "tcp:") && !STRPREFIX(uri, "tcp://")) {
|
||||||
|
/* HACK: source host generates bogus URIs, so fix them up */
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
if (!uribits) {
|
||||||
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("cannot parse URI %s"), uri);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resource > 0 &&
|
||||||
|
qemuMonitorSetMigrationSpeed(vm, resource) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (qemuMonitorMigrateToHost(vm, 0, 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"
|
||||||
|
*/
|
||||||
|
if (qemuMonitorGetMigrationStatus(vm, &status,
|
||||||
|
&transferred,
|
||||||
|
&remaining,
|
||||||
|
&total) < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != QEMU_MONITOR_MIGRATION_STATUS_COMPLETED) {
|
||||||
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
||||||
|
"%s", _("migrate did not successfully complete"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
xmlFreeURI(uribits);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int doTunnelMigrate(virDomainPtr dom,
|
static int doTunnelMigrate(virDomainPtr dom,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
const char *uri,
|
const char *uri,
|
||||||
@ -6548,6 +6614,8 @@ static int doTunnelMigrate(virDomainPtr dom,
|
|||||||
goto qemu_cancel_migration;
|
goto qemu_cancel_migration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* XXX should honour the 'resource' parameter here */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
bytes = saferead(client_sock, buffer, sizeof(buffer));
|
bytes = saferead(client_sock, buffer, sizeof(buffer));
|
||||||
if (bytes < 0) {
|
if (bytes < 0) {
|
||||||
@ -6612,7 +6680,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
|
|||||||
int cookielen ATTRIBUTE_UNUSED,
|
int cookielen ATTRIBUTE_UNUSED,
|
||||||
const char *uri,
|
const char *uri,
|
||||||
unsigned long flags,
|
unsigned long flags,
|
||||||
const char *dname ATTRIBUTE_UNUSED,
|
const char *dname,
|
||||||
unsigned long resource)
|
unsigned long resource)
|
||||||
{
|
{
|
||||||
struct qemud_driver *driver = dom->conn->privateData;
|
struct qemud_driver *driver = dom->conn->privateData;
|
||||||
@ -6620,9 +6688,6 @@ qemudDomainMigratePerform (virDomainPtr dom,
|
|||||||
virDomainEventPtr event = NULL;
|
virDomainEventPtr event = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
int paused = 0;
|
int paused = 0;
|
||||||
int status;
|
|
||||||
xmlURIPtr uribits = NULL;
|
|
||||||
unsigned long long transferred, remaining, total;
|
|
||||||
|
|
||||||
qemuDriverLock(driver);
|
qemuDriverLock(driver);
|
||||||
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
||||||
@ -6654,53 +6719,13 @@ qemudDomainMigratePerform (virDomainPtr dom,
|
|||||||
event = NULL;
|
event = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resource > 0 &&
|
if ((flags & VIR_MIGRATE_TUNNELLED)) {
|
||||||
qemuMonitorSetMigrationSpeed(vm, resource) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (!(flags & VIR_MIGRATE_TUNNELLED)) {
|
|
||||||
/* Issue the migrate command. */
|
|
||||||
if (STRPREFIX(uri, "tcp:") && !STRPREFIX(uri, "tcp://")) {
|
|
||||||
/* HACK: source host generates bogus URIs, so fix them up */
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
if (!uribits) {
|
|
||||||
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("cannot parse URI %s"), uri);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qemuMonitorMigrateToHost(vm, 0, 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"
|
|
||||||
*/
|
|
||||||
if (qemuMonitorGetMigrationStatus(vm, &status,
|
|
||||||
&transferred,
|
|
||||||
&remaining,
|
|
||||||
&total) < 0) {
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status != QEMU_MONITOR_MIGRATION_STATUS_COMPLETED) {
|
|
||||||
qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
|
||||||
"%s", _("migrate did not successfully complete"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (doTunnelMigrate(dom, vm, uri, flags, dname, resource) < 0)
|
if (doTunnelMigrate(dom, vm, uri, flags, dname, resource) < 0)
|
||||||
/* doTunnelMigrate already set the error, so just get out */
|
/* doTunnelMigrate already set the error, so just get out */
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
} else {
|
||||||
|
if (doNativeMigrate(dom, vm, uri, flags, dname, resource) < 0)
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clean up the source domain. */
|
/* Clean up the source domain. */
|
||||||
@ -6733,8 +6758,6 @@ cleanup:
|
|||||||
VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
|
VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uribits)
|
|
||||||
xmlFreeURI(uribits);
|
|
||||||
if (vm)
|
if (vm)
|
||||||
virDomainObjUnlock(vm);
|
virDomainObjUnlock(vm);
|
||||||
if (event)
|
if (event)
|
||||||
|
Loading…
Reference in New Issue
Block a user