mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-02 20:58:33 +03:00
qemu: Allow migration to be cancelled at prepare phase
Currently, if user calls virDomainAbortJob we just issue 'migrate_cancel' and hope for the best. However, if user calls the API in wrong phase when migration hasn't been started yet (perform phase) the cancel request is just ignored. With this patch, the request is remembered and as soon as perform phase starts, migration is cancelled.
This commit is contained in:
parent
b1c88c1476
commit
ab5e7d4977
@ -160,6 +160,7 @@ qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv)
|
||||
job->mask = DEFAULT_JOB_MASK;
|
||||
job->start = 0;
|
||||
job->dump_memory_only = false;
|
||||
job->asyncAbort = false;
|
||||
memset(&job->info, 0, sizeof(job->info));
|
||||
}
|
||||
|
||||
@ -959,6 +960,17 @@ qemuDomainObjEndAsyncJob(struct qemud_driver *driver, virDomainObjPtr obj)
|
||||
return virObjectUnref(obj);
|
||||
}
|
||||
|
||||
void
|
||||
qemuDomainObjAbortAsyncJob(virDomainObjPtr obj)
|
||||
{
|
||||
qemuDomainObjPrivatePtr priv = obj->privateData;
|
||||
|
||||
VIR_DEBUG("Requesting abort of async job: %s",
|
||||
qemuDomainAsyncJobTypeToString(priv->job.asyncJob));
|
||||
|
||||
priv->job.asyncAbort = true;
|
||||
}
|
||||
|
||||
static int
|
||||
qemuDomainObjEnterMonitorInternal(struct qemud_driver *driver,
|
||||
bool driver_locked,
|
||||
|
@ -111,6 +111,7 @@ struct qemuDomainJobObj {
|
||||
unsigned long long start; /* When the async job started */
|
||||
bool dump_memory_only; /* use dump-guest-memory to do dump */
|
||||
virDomainJobInfo info; /* Async job progress data */
|
||||
bool asyncAbort; /* abort of async job requested */
|
||||
};
|
||||
|
||||
typedef struct _qemuDomainPCIAddressSet qemuDomainPCIAddressSet;
|
||||
@ -204,6 +205,7 @@ bool qemuDomainObjEndJob(struct qemud_driver *driver,
|
||||
bool qemuDomainObjEndAsyncJob(struct qemud_driver *driver,
|
||||
virDomainObjPtr obj)
|
||||
ATTRIBUTE_RETURN_CHECK;
|
||||
void qemuDomainObjAbortAsyncJob(virDomainObjPtr obj);
|
||||
void qemuDomainObjSetJobPhase(struct qemud_driver *driver,
|
||||
virDomainObjPtr obj,
|
||||
int phase);
|
||||
|
@ -10397,6 +10397,7 @@ static int qemuDomainAbortJob(virDomainPtr dom) {
|
||||
}
|
||||
|
||||
VIR_DEBUG("Cancelling job at client request");
|
||||
qemuDomainObjAbortAsyncJob(vm);
|
||||
qemuDomainObjEnterMonitor(driver, vm);
|
||||
ret = qemuMonitorMigrateCancel(priv->mon);
|
||||
qemuDomainObjExitMonitor(driver, vm);
|
||||
|
@ -2168,6 +2168,17 @@ qemuMigrationRun(struct qemud_driver *driver,
|
||||
QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (priv->job.asyncAbort) {
|
||||
/* explicitly do this *after* we entered the monitor,
|
||||
* as this is a critical section so we are guaranteed
|
||||
* priv->job.asyncAbort will not change */
|
||||
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
||||
virReportError(VIR_ERR_OPERATION_ABORTED, _("%s: %s"),
|
||||
qemuDomainAsyncJobTypeToString(priv->job.asyncJob),
|
||||
_("canceled by client"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (qemuMonitorSetMigrationSpeed(priv->mon, migrate_speed) < 0) {
|
||||
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
||||
goto cleanup;
|
||||
|
Loading…
x
Reference in New Issue
Block a user