Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx> --- Notes: Version 2: - no change src/qemu/qemu_process.c | 206 ++++++++++++++++++++++++++---------------------- 1 file changed, 110 insertions(+), 96 deletions(-) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 879cd12..a0c93c9 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3265,113 +3265,122 @@ qemuProcessUpdateState(virQEMUDriverPtr driver, virDomainObjPtr vm) } static int -qemuProcessRecoverMigration(virQEMUDriverPtr driver, - virDomainObjPtr vm, - virConnectPtr conn, - qemuDomainAsyncJob job, - qemuMigrationJobPhase phase, - virDomainState state, - int reason) +qemuProcessRecoverMigrationIn(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virConnectPtr conn, + qemuMigrationJobPhase phase, + virDomainState state, + int reason ATTRIBUTE_UNUSED) { - if (job == QEMU_ASYNC_JOB_MIGRATION_IN) { - switch (phase) { - case QEMU_MIGRATION_PHASE_NONE: - case QEMU_MIGRATION_PHASE_PERFORM2: - case QEMU_MIGRATION_PHASE_BEGIN3: - case QEMU_MIGRATION_PHASE_PERFORM3: - case QEMU_MIGRATION_PHASE_PERFORM3_DONE: - case QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED: - case QEMU_MIGRATION_PHASE_CONFIRM3: - case QEMU_MIGRATION_PHASE_LAST: - break; + switch (phase) { + case QEMU_MIGRATION_PHASE_NONE: + case QEMU_MIGRATION_PHASE_PERFORM2: + case QEMU_MIGRATION_PHASE_BEGIN3: + case QEMU_MIGRATION_PHASE_PERFORM3: + case QEMU_MIGRATION_PHASE_PERFORM3_DONE: + case QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED: + case QEMU_MIGRATION_PHASE_CONFIRM3: + case QEMU_MIGRATION_PHASE_LAST: + /* N/A for incoming migration */ + break; - case QEMU_MIGRATION_PHASE_PREPARE: - VIR_DEBUG("Killing unfinished incoming migration for domain %s", - vm->def->name); + case QEMU_MIGRATION_PHASE_PREPARE: + VIR_DEBUG("Killing unfinished incoming migration for domain %s", + vm->def->name); + return -1; + + case QEMU_MIGRATION_PHASE_FINISH2: + /* source domain is already killed so let's just resume the domain + * and hope we are all set */ + VIR_DEBUG("Incoming migration finished, resuming domain %s", + vm->def->name); + if (qemuProcessStartCPUs(driver, vm, conn, + VIR_DOMAIN_RUNNING_UNPAUSED, + QEMU_ASYNC_JOB_NONE) < 0) { + VIR_WARN("Could not resume domain %s", vm->def->name); + } + break; + + case QEMU_MIGRATION_PHASE_FINISH3: + /* migration finished, we started resuming the domain but didn't + * confirm success or failure yet; killing it seems safest unless + * we already started guest CPUs */ + if (state != VIR_DOMAIN_RUNNING) { + VIR_DEBUG("Killing migrated domain %s", vm->def->name); return -1; + } + break; + } - case QEMU_MIGRATION_PHASE_FINISH2: - /* source domain is already killed so let's just resume the domain - * and hope we are all set */ - VIR_DEBUG("Incoming migration finished, resuming domain %s", - vm->def->name); - if (qemuProcessStartCPUs(driver, vm, conn, - VIR_DOMAIN_RUNNING_UNPAUSED, - QEMU_ASYNC_JOB_NONE) < 0) { - VIR_WARN("Could not resume domain %s", vm->def->name); - } - break; + return 0; +} - case QEMU_MIGRATION_PHASE_FINISH3: - /* migration finished, we started resuming the domain but didn't - * confirm success or failure yet; killing it seems safest unless - * we already started guest CPUs */ - if (state != VIR_DOMAIN_RUNNING) { - VIR_DEBUG("Killing migrated domain %s", vm->def->name); - return -1; - } - break; +static int +qemuProcessRecoverMigrationOut(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virConnectPtr conn, + qemuMigrationJobPhase phase, + virDomainState state, + int reason) +{ + switch (phase) { + case QEMU_MIGRATION_PHASE_NONE: + case QEMU_MIGRATION_PHASE_PREPARE: + case QEMU_MIGRATION_PHASE_FINISH2: + case QEMU_MIGRATION_PHASE_FINISH3: + case QEMU_MIGRATION_PHASE_LAST: + /* N/A for outgoing migration */ + break; + + case QEMU_MIGRATION_PHASE_BEGIN3: + /* nothing happened so far, just forget we were about to migrate the + * domain */ + break; + + case QEMU_MIGRATION_PHASE_PERFORM2: + case QEMU_MIGRATION_PHASE_PERFORM3: + /* migration is still in progress, let's cancel it and resume the + * domain */ + VIR_DEBUG("Cancelling unfinished migration of domain %s", + vm->def->name); + if (qemuMigrationCancel(driver, vm) < 0) { + VIR_WARN("Could not cancel ongoing migration of domain %s", + vm->def->name); } - } else if (job == QEMU_ASYNC_JOB_MIGRATION_OUT) { - switch (phase) { - case QEMU_MIGRATION_PHASE_NONE: - case QEMU_MIGRATION_PHASE_PREPARE: - case QEMU_MIGRATION_PHASE_FINISH2: - case QEMU_MIGRATION_PHASE_FINISH3: - case QEMU_MIGRATION_PHASE_LAST: - break; + goto resume; - case QEMU_MIGRATION_PHASE_BEGIN3: - /* nothing happen so far, just forget we were about to migrate the - * domain */ - break; + case QEMU_MIGRATION_PHASE_PERFORM3_DONE: + /* migration finished but we didn't have a chance to get the result + * of Finish3 step; third party needs to check what to do next + */ + break; - case QEMU_MIGRATION_PHASE_PERFORM2: - case QEMU_MIGRATION_PHASE_PERFORM3: - /* migration is still in progress, let's cancel it and resume the - * domain */ - if (qemuMigrationCancel(driver, vm) < 0) - return -1; - /* resume the domain but only if it was paused as a result of - * migration */ - if (state == VIR_DOMAIN_PAUSED && - (reason == VIR_DOMAIN_PAUSED_MIGRATION || - reason == VIR_DOMAIN_PAUSED_UNKNOWN)) { - if (qemuProcessStartCPUs(driver, vm, conn, - VIR_DOMAIN_RUNNING_UNPAUSED, - QEMU_ASYNC_JOB_NONE) < 0) { - VIR_WARN("Could not resume domain %s", vm->def->name); - } - } - break; + case QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED: + /* Finish3 failed, we need to resume the domain */ + VIR_DEBUG("Resuming domain %s after failed migration", + vm->def->name); + goto resume; - case QEMU_MIGRATION_PHASE_PERFORM3_DONE: - /* migration finished but we didn't have a chance to get the result - * of Finish3 step; third party needs to check what to do next - */ - break; + case QEMU_MIGRATION_PHASE_CONFIRM3: + /* migration completed, we need to kill the domain here */ + return -1; + } - case QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED: - /* Finish3 failed, we need to resume the domain */ - VIR_DEBUG("Resuming domain %s after failed migration", - vm->def->name); - if (state == VIR_DOMAIN_PAUSED && - (reason == VIR_DOMAIN_PAUSED_MIGRATION || - reason == VIR_DOMAIN_PAUSED_UNKNOWN)) { - if (qemuProcessStartCPUs(driver, vm, conn, - VIR_DOMAIN_RUNNING_UNPAUSED, - QEMU_ASYNC_JOB_NONE) < 0) { - VIR_WARN("Could not resume domain %s", vm->def->name); - } - } - break; + return 0; - case QEMU_MIGRATION_PHASE_CONFIRM3: - /* migration completed, we need to kill the domain here */ - return -1; + resume: + /* resume the domain but only if it was paused as a result of + * migration + */ + if (state == VIR_DOMAIN_PAUSED && + (reason == VIR_DOMAIN_PAUSED_MIGRATION || + reason == VIR_DOMAIN_PAUSED_UNKNOWN)) { + if (qemuProcessStartCPUs(driver, vm, conn, + VIR_DOMAIN_RUNNING_UNPAUSED, + QEMU_ASYNC_JOB_NONE) < 0) { + VIR_WARN("Could not resume domain %s", vm->def->name); } } - return 0; } @@ -3389,9 +3398,14 @@ qemuProcessRecoverJob(virQEMUDriverPtr driver, switch (job->asyncJob) { case QEMU_ASYNC_JOB_MIGRATION_OUT: + if (qemuProcessRecoverMigrationOut(driver, vm, conn, job->phase, + state, reason) < 0) + return -1; + break; + case QEMU_ASYNC_JOB_MIGRATION_IN: - if (qemuProcessRecoverMigration(driver, vm, conn, job->asyncJob, - job->phase, state, reason) < 0) + if (qemuProcessRecoverMigrationIn(driver, vm, conn, job->phase, + state, reason) < 0) return -1; break; -- 2.7.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list