mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 19:32:19 +00:00
qemu: Introduce qemuProcessBeginStopJob
When destroying a domain we need to make sure we will be able to start a job no matter what other operations are running or even stuck in a job. This is done by killing the domain before starting the destroy job. Let's introduce qemuProcessBeginStopJob which combines killing a domain and starting a job in a single API which can be called everywhere we need a job to stop a domain. Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
parent
b7a948be01
commit
4d0c535a36
@ -2279,33 +2279,10 @@ qemuDomainDestroyFlags(virDomainPtr dom,
|
||||
if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN)
|
||||
stopFlags |= VIR_QEMU_PROCESS_STOP_MIGRATED;
|
||||
|
||||
/* We need to prevent monitor EOF callback from doing our work (and sending
|
||||
* misleading events) while the vm is unlocked inside BeginJob/ProcessKill API
|
||||
*/
|
||||
priv->beingDestroyed = true;
|
||||
|
||||
/* Although qemuProcessStop does this already, there may
|
||||
* be an outstanding job active. We want to make sure we
|
||||
* can kill the process even if a job is active. Killing
|
||||
* it now means the job will be released
|
||||
*/
|
||||
if (flags & VIR_DOMAIN_DESTROY_GRACEFUL) {
|
||||
if (qemuProcessKill(vm, 0) < 0) {
|
||||
priv->beingDestroyed = false;
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
if (qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_FORCE) < 0) {
|
||||
priv->beingDestroyed = false;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_DESTROY) < 0)
|
||||
if (qemuProcessBeginStopJob(driver, vm, QEMU_JOB_DESTROY,
|
||||
!(flags & VIR_DOMAIN_DESTROY_GRACEFUL)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
priv->beingDestroyed = false;
|
||||
|
||||
if (!virDomainObjIsActive(vm)) {
|
||||
virReportError(VIR_ERR_OPERATION_INVALID,
|
||||
"%s", _("domain is not running"));
|
||||
|
@ -5403,6 +5403,45 @@ qemuProcessKill(virDomainObjPtr vm, unsigned int flags)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* qemuProcessBeginStopJob:
|
||||
*
|
||||
* Stop all current jobs by killing the domain and start a new one for
|
||||
* qemuProcessStop.
|
||||
*/
|
||||
int
|
||||
qemuProcessBeginStopJob(virQEMUDriverPtr driver,
|
||||
virDomainObjPtr vm,
|
||||
qemuDomainJob job,
|
||||
bool forceKill)
|
||||
{
|
||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||
unsigned int killFlags = forceKill ? VIR_QEMU_PROCESS_KILL_FORCE : 0;
|
||||
int ret = -1;
|
||||
|
||||
/* We need to prevent monitor EOF callback from doing our work (and
|
||||
* sending misleading events) while the vm is unlocked inside
|
||||
* BeginJob/ProcessKill API
|
||||
*/
|
||||
priv->beingDestroyed = true;
|
||||
|
||||
if (qemuProcessKill(vm, killFlags) < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* Wake up anything waiting on domain condition */
|
||||
virDomainObjBroadcast(vm);
|
||||
|
||||
if (qemuDomainObjBeginJob(driver, vm, job) < 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
priv->beingDestroyed = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void qemuProcessStop(virQEMUDriverPtr driver,
|
||||
virDomainObjPtr vm,
|
||||
virDomainShutoffReason reason,
|
||||
|
@ -114,6 +114,10 @@ typedef enum {
|
||||
VIR_QEMU_PROCESS_STOP_NO_RELABEL = 1 << 1,
|
||||
} qemuProcessStopFlags;
|
||||
|
||||
int qemuProcessBeginStopJob(virQEMUDriverPtr driver,
|
||||
virDomainObjPtr vm,
|
||||
qemuDomainJob job,
|
||||
bool forceKill);
|
||||
void qemuProcessStop(virQEMUDriverPtr driver,
|
||||
virDomainObjPtr vm,
|
||||
virDomainShutoffReason reason,
|
||||
|
Loading…
x
Reference in New Issue
Block a user