--- src/qemu/qemu_driver.c | 71 +++----------------------------------- src/qemu/qemu_migration.c | 86 +++++++++++++++++++++++++++++++++++++++++++++-- src/qemu/qemu_migration.h | 2 +- 3 files changed, 89 insertions(+), 70 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index dbe344c..863923d 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -10200,81 +10200,20 @@ qemuDomainMigrateBegin3(virDomainPtr domain, const char *dname, unsigned long resource ATTRIBUTE_UNUSED) { - virQEMUDriverPtr driver = domain->conn->privateData; virDomainObjPtr vm; - char *xml = NULL; - enum qemuDomainAsyncJob asyncJob; virCheckFlags(QEMU_MIGRATION_FLAGS, NULL); if (!(vm = qemuDomObjFromDomain(domain))) return NULL; - if (virDomainMigrateBegin3EnsureACL(domain->conn, vm->def) < 0) - goto cleanup; - - if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) { - if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) - goto cleanup; - asyncJob = QEMU_ASYNC_JOB_MIGRATION_OUT; - } else { - if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) - goto cleanup; - asyncJob = QEMU_ASYNC_JOB_NONE; - } - - if (!virDomainObjIsActive(vm) && !(flags & VIR_MIGRATE_OFFLINE)) { - virReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("domain is not running")); - goto endjob; - } - - /* Check if there is any ejected media. - * We don't want to require them on the destination. - */ - if (!(flags & VIR_MIGRATE_OFFLINE) && - qemuDomainCheckEjectableMedia(driver, vm, asyncJob) < 0) - goto endjob; - - if (!(xml = qemuMigrationBegin(driver, vm, xmlin, dname, - cookieout, cookieoutlen, - flags))) - goto endjob; - - if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) { - /* We keep the job active across API calls until the confirm() call. - * This prevents any other APIs being invoked while migration is taking - * place. - */ - if (virQEMUCloseCallbacksSet(driver->closeCallbacks, vm, domain->conn, - qemuMigrationCleanup) < 0) - goto endjob; - if (qemuMigrationJobContinue(vm) == 0) { - vm = NULL; - virReportError(VIR_ERR_OPERATION_FAILED, - "%s", _("domain disappeared")); - VIR_FREE(xml); - if (cookieout) - VIR_FREE(*cookieout); - } - } else { - goto endjob; - } - -cleanup: - if (vm) + if (virDomainMigrateBegin3EnsureACL(domain->conn, vm->def) < 0) { virObjectUnlock(vm); - return xml; - -endjob: - if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) { - if (qemuMigrationJobFinish(driver, vm) == 0) - vm = NULL; - } else { - if (qemuDomainObjEndJob(driver, vm) == 0) - vm = NULL; + return NULL; } - goto cleanup; + + return qemuMigrationBegin(domain->conn, vm, xmlin, dname, + cookieout, cookieoutlen, flags); } static int diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 8de38fe..9e2d043 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -39,6 +39,7 @@ #include "qemu_capabilities.h" #include "qemu_command.h" #include "qemu_cgroup.h" +#include "qemu_hotplug.h" #include "domain_audit.h" #include "virlog.h" @@ -1923,8 +1924,10 @@ cleanup: return vm; } + /* The caller is supposed to lock the vm and start a migration job. */ -char *qemuMigrationBegin(virQEMUDriverPtr driver, +static char +*qemuMigrationBeginPhase(virQEMUDriverPtr driver, virDomainObjPtr vm, const char *xmlin, const char *dname, @@ -2024,6 +2027,83 @@ cleanup: return rv; } +char * +qemuMigrationBegin(virConnectPtr conn, + virDomainObjPtr vm, + const char *xmlin, + const char *dname, + char **cookieout, + int *cookieoutlen, + unsigned long flags) +{ + virQEMUDriverPtr driver = conn->privateData; + char *xml = NULL; + enum qemuDomainAsyncJob asyncJob; + + if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) { + if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) + goto cleanup; + asyncJob = QEMU_ASYNC_JOB_MIGRATION_OUT; + } else { + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) + goto cleanup; + asyncJob = QEMU_ASYNC_JOB_NONE; + } + + if (!virDomainObjIsActive(vm) && !(flags & VIR_MIGRATE_OFFLINE)) { + virReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("domain is not running")); + goto endjob; + } + + /* Check if there is any ejected media. + * We don't want to require them on the destination. + */ + if (!(flags & VIR_MIGRATE_OFFLINE) && + qemuDomainCheckEjectableMedia(driver, vm, asyncJob) < 0) + goto endjob; + + if (!(xml = qemuMigrationBeginPhase(driver, vm, xmlin, dname, + cookieout, cookieoutlen, + flags))) + goto endjob; + + if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) { + /* We keep the job active across API calls until the confirm() call. + * This prevents any other APIs being invoked while migration is taking + * place. + */ + if (virQEMUCloseCallbacksSet(driver->closeCallbacks, vm, conn, + qemuMigrationCleanup) < 0) + goto endjob; + if (qemuMigrationJobContinue(vm) == 0) { + vm = NULL; + virReportError(VIR_ERR_OPERATION_FAILED, + "%s", _("domain disappeared")); + VIR_FREE(xml); + if (cookieout) + VIR_FREE(*cookieout); + } + } else { + goto endjob; + } + +cleanup: + if (vm) + virObjectUnlock(vm); + return xml; + +endjob: + if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) { + if (qemuMigrationJobFinish(driver, vm) == 0) + vm = NULL; + } else { + if (qemuDomainObjEndJob(driver, vm) == 0) + vm = NULL; + } + goto cleanup; +} + /* Prepare is the first step, and it runs on the destination host. */ @@ -3341,8 +3421,8 @@ static int doPeer2PeerMigrate3(virQEMUDriverPtr driver, * bit here, because we are already running inside the context of * a single job. */ - dom_xml = qemuMigrationBegin(driver, vm, xmlin, dname, - &cookieout, &cookieoutlen, flags); + dom_xml = qemuMigrationBeginPhase(driver, vm, xmlin, dname, + &cookieout, &cookieoutlen, flags); if (!dom_xml) goto cleanup; diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index 5b21ca2..09b5b1a 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -84,7 +84,7 @@ virDomainObjPtr qemuMigrationCleanup(virQEMUDriverPtr driver, virDomainObjPtr vm, virConnectPtr conn); -char *qemuMigrationBegin(virQEMUDriverPtr driver, +char *qemuMigrationBegin(virConnectPtr conn, virDomainObjPtr vm, const char *xmlin, const char *dname, -- 1.8.2.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list