mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
qemu: Unite error handling in qemuMigrationRun
Merge cancel and cancelPostCopy sections with the generic error section, where we can easily decide whether canceling the ongoing migration is required. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> Reviewed-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
parent
c1a643b68f
commit
7d2fbabcaf
@ -3621,7 +3621,7 @@ qemuMigrationRun(virQEMUDriverPtr driver,
|
|||||||
unsigned int cookieFlags = 0;
|
unsigned int cookieFlags = 0;
|
||||||
bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR);
|
bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR);
|
||||||
bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
|
bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
|
||||||
bool inPostCopy = false;
|
bool cancel = false;
|
||||||
unsigned int waitFlags;
|
unsigned int waitFlags;
|
||||||
virDomainDefPtr persistDef = NULL;
|
virDomainDefPtr persistDef = NULL;
|
||||||
char *timestamp;
|
char *timestamp;
|
||||||
@ -3827,10 +3827,11 @@ qemuMigrationRun(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
/* From this point onwards we *must* call cancel to abort the
|
/* From this point onwards we *must* call cancel to abort the
|
||||||
* migration on source if anything goes wrong */
|
* migration on source if anything goes wrong */
|
||||||
|
cancel = true;
|
||||||
|
|
||||||
if (spec->fwdType != MIGRATION_FWD_DIRECT) {
|
if (spec->fwdType != MIGRATION_FWD_DIRECT) {
|
||||||
if (!(iothread = qemuMigrationStartTunnel(spec->fwd.stream, fd)))
|
if (!(iothread = qemuMigrationStartTunnel(spec->fwd.stream, fd)))
|
||||||
goto cancel;
|
goto error;
|
||||||
/* If we've created a tunnel, then the 'fd' will be closed in the
|
/* If we've created a tunnel, then the 'fd' will be closed in the
|
||||||
* qemuMigrationIOFunc as data->sock.
|
* qemuMigrationIOFunc as data->sock.
|
||||||
*/
|
*/
|
||||||
@ -3848,13 +3849,13 @@ qemuMigrationRun(virQEMUDriverPtr driver,
|
|||||||
rc = qemuMigrationWaitForCompletion(driver, vm,
|
rc = qemuMigrationWaitForCompletion(driver, vm,
|
||||||
QEMU_ASYNC_JOB_MIGRATION_OUT,
|
QEMU_ASYNC_JOB_MIGRATION_OUT,
|
||||||
dconn, waitFlags);
|
dconn, waitFlags);
|
||||||
if (rc == -2)
|
if (rc == -2) {
|
||||||
goto cancel;
|
|
||||||
else if (rc == -1)
|
|
||||||
goto error;
|
goto error;
|
||||||
|
} else if (rc == -1) {
|
||||||
if (priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY)
|
/* QEMU reported failed migration, nothing to cancel anymore */
|
||||||
inPostCopy = true;
|
cancel = false;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* When migration completed, QEMU will have paused the CPUs for us.
|
/* When migration completed, QEMU will have paused the CPUs for us.
|
||||||
* Wait for the STOP event to be processed or explicitly stop CPUs
|
* Wait for the STOP event to be processed or explicitly stop CPUs
|
||||||
@ -3866,25 +3867,25 @@ qemuMigrationRun(virQEMUDriverPtr driver,
|
|||||||
rc = virDomainObjWait(vm);
|
rc = virDomainObjWait(vm);
|
||||||
priv->signalStop = false;
|
priv->signalStop = false;
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
goto cancelPostCopy;
|
goto error;
|
||||||
}
|
}
|
||||||
} else if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING &&
|
} else if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING &&
|
||||||
qemuMigrationSetOffline(driver, vm) < 0) {
|
qemuMigrationSetOffline(driver, vm) < 0) {
|
||||||
goto cancelPostCopy;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mig && mig->nbd &&
|
if (mig && mig->nbd &&
|
||||||
qemuMigrationCancelDriveMirror(driver, vm, true,
|
qemuMigrationCancelDriveMirror(driver, vm, true,
|
||||||
QEMU_ASYNC_JOB_MIGRATION_OUT,
|
QEMU_ASYNC_JOB_MIGRATION_OUT,
|
||||||
dconn) < 0)
|
dconn) < 0)
|
||||||
goto cancelPostCopy;
|
goto error;
|
||||||
|
|
||||||
if (iothread) {
|
if (iothread) {
|
||||||
qemuMigrationIOThreadPtr io;
|
qemuMigrationIOThreadPtr io;
|
||||||
|
|
||||||
VIR_STEAL_PTR(io, iothread);
|
VIR_STEAL_PTR(io, iothread);
|
||||||
if (qemuMigrationStopTunnel(io, false) < 0)
|
if (qemuMigrationStopTunnel(io, false) < 0)
|
||||||
goto cancelPostCopy;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->job.completed) {
|
if (priv->job.completed) {
|
||||||
@ -3924,8 +3925,16 @@ qemuMigrationRun(virQEMUDriverPtr driver,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (!orig_err)
|
orig_err = virSaveLastError();
|
||||||
orig_err = virSaveLastError();
|
|
||||||
|
if (cancel &&
|
||||||
|
priv->job.current->status != QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED &&
|
||||||
|
virDomainObjIsActive(vm) &&
|
||||||
|
qemuDomainObjEnterMonitorAsync(driver, vm,
|
||||||
|
QEMU_ASYNC_JOB_MIGRATION_OUT) == 0) {
|
||||||
|
qemuMonitorMigrateCancel(priv->mon);
|
||||||
|
ignore_value(qemuDomainObjExitMonitor(driver, vm));
|
||||||
|
}
|
||||||
|
|
||||||
/* cancel any outstanding NBD jobs */
|
/* cancel any outstanding NBD jobs */
|
||||||
if (mig && mig->nbd)
|
if (mig && mig->nbd)
|
||||||
@ -3937,7 +3946,8 @@ qemuMigrationRun(virQEMUDriverPtr driver,
|
|||||||
qemuMigrationStopTunnel(iothread, true);
|
qemuMigrationStopTunnel(iothread, true);
|
||||||
|
|
||||||
if (priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_ACTIVE ||
|
if (priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_ACTIVE ||
|
||||||
priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_MIGRATING)
|
priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_MIGRATING ||
|
||||||
|
priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY)
|
||||||
priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_FAILED;
|
priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_FAILED;
|
||||||
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -3945,25 +3955,6 @@ qemuMigrationRun(virQEMUDriverPtr driver,
|
|||||||
exit_monitor:
|
exit_monitor:
|
||||||
ignore_value(qemuDomainObjExitMonitor(driver, vm));
|
ignore_value(qemuDomainObjExitMonitor(driver, vm));
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
cancel:
|
|
||||||
orig_err = virSaveLastError();
|
|
||||||
|
|
||||||
if (virDomainObjIsActive(vm)) {
|
|
||||||
if (qemuDomainObjEnterMonitorAsync(driver, vm,
|
|
||||||
QEMU_ASYNC_JOB_MIGRATION_OUT) == 0) {
|
|
||||||
qemuMonitorMigrateCancel(priv->mon);
|
|
||||||
ignore_value(qemuDomainObjExitMonitor(driver, vm));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
cancelPostCopy:
|
|
||||||
priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_FAILED;
|
|
||||||
if (inPostCopy)
|
|
||||||
goto cancel;
|
|
||||||
else
|
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform migration using QEMU's native migrate support,
|
/* Perform migration using QEMU's native migrate support,
|
||||||
|
Loading…
Reference in New Issue
Block a user