mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 11:22:23 +00:00
qemu: Refactor qemuDomainBlockJobAbort()
Change few variable names and refactor the code flow. As an additional bonus the function now fails if the event state is not as expected.
This commit is contained in:
parent
8a609afb6f
commit
634285f9c1
@ -16355,13 +16355,13 @@ qemuDomainBlockJobAbort(virDomainPtr dom,
|
|||||||
{
|
{
|
||||||
virQEMUDriverPtr driver = dom->conn->privateData;
|
virQEMUDriverPtr driver = dom->conn->privateData;
|
||||||
char *device = NULL;
|
char *device = NULL;
|
||||||
virObjectEventPtr event = NULL;
|
|
||||||
virObjectEventPtr event2 = NULL;
|
|
||||||
virDomainDiskDefPtr disk;
|
virDomainDiskDefPtr disk;
|
||||||
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
||||||
bool save = false;
|
bool save = false;
|
||||||
int idx;
|
int idx;
|
||||||
bool async;
|
bool modern;
|
||||||
|
bool pivot = !!(flags & VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT);
|
||||||
|
bool async = !!(flags & VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC);
|
||||||
virDomainObjPtr vm;
|
virDomainObjPtr vm;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
@ -16374,7 +16374,7 @@ qemuDomainBlockJobAbort(virDomainPtr dom,
|
|||||||
if (virDomainBlockJobAbortEnsureACL(dom->conn, vm->def) < 0)
|
if (virDomainBlockJobAbortEnsureACL(dom->conn, vm->def) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (qemuDomainSupportsBlockJobs(vm, &async) < 0)
|
if (qemuDomainSupportsBlockJobs(vm, &modern) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
|
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
|
||||||
@ -16390,19 +16390,14 @@ qemuDomainBlockJobAbort(virDomainPtr dom,
|
|||||||
goto endjob;
|
goto endjob;
|
||||||
disk = vm->def->disks[idx];
|
disk = vm->def->disks[idx];
|
||||||
|
|
||||||
if (async && !(flags & VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC)) {
|
if (modern && !async) {
|
||||||
/* prepare state for event delivery */
|
/* prepare state for event delivery. Since qemuDomainBlockPivot is
|
||||||
|
* synchronous, but the event is delivered asynchronously we need to
|
||||||
|
* wait too */
|
||||||
disk->blockJobStatus = -1;
|
disk->blockJobStatus = -1;
|
||||||
disk->blockJobSync = true;
|
disk->blockJobSync = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT) &&
|
|
||||||
!(async && disk->mirror)) {
|
|
||||||
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
||||||
_("pivot of disk '%s' requires an active copy job"),
|
|
||||||
disk->dst);
|
|
||||||
goto endjob;
|
|
||||||
}
|
|
||||||
if (disk->mirrorState != VIR_DOMAIN_DISK_MIRROR_STATE_NONE &&
|
if (disk->mirrorState != VIR_DOMAIN_DISK_MIRROR_STATE_NONE &&
|
||||||
disk->mirrorState != VIR_DOMAIN_DISK_MIRROR_STATE_READY) {
|
disk->mirrorState != VIR_DOMAIN_DISK_MIRROR_STATE_READY) {
|
||||||
virReportError(VIR_ERR_OPERATION_INVALID,
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
||||||
@ -16411,31 +16406,31 @@ qemuDomainBlockJobAbort(virDomainPtr dom,
|
|||||||
goto endjob;
|
goto endjob;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (disk->mirror && (flags & VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT)) {
|
if (pivot) {
|
||||||
ret = qemuDomainBlockPivot(driver, vm, device, disk);
|
if ((ret = qemuDomainBlockPivot(driver, vm, device, disk)) < 0) {
|
||||||
if (ret < 0 && async) {
|
|
||||||
disk->blockJobSync = false;
|
disk->blockJobSync = false;
|
||||||
goto endjob;
|
goto endjob;
|
||||||
}
|
}
|
||||||
goto waitjob;
|
} else {
|
||||||
}
|
if (disk->mirror) {
|
||||||
if (disk->mirror) {
|
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_ABORT;
|
||||||
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_ABORT;
|
save = true;
|
||||||
save = true;
|
}
|
||||||
|
|
||||||
|
qemuDomainObjEnterMonitor(driver, vm);
|
||||||
|
ret = qemuMonitorBlockJobCancel(qemuDomainGetMonitor(vm), device, modern);
|
||||||
|
if (qemuDomainObjExitMonitor(driver, vm) < 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto endjob;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
if (disk->mirror)
|
||||||
|
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
|
||||||
|
goto endjob;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qemuDomainObjEnterMonitor(driver, vm);
|
|
||||||
ret = qemuMonitorBlockJobCancel(qemuDomainGetMonitor(vm), device, async);
|
|
||||||
if (qemuDomainObjExitMonitor(driver, vm) < 0)
|
|
||||||
ret = -1;
|
|
||||||
|
|
||||||
if (ret < 0) {
|
|
||||||
if (disk->mirror)
|
|
||||||
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
|
|
||||||
goto endjob;
|
|
||||||
}
|
|
||||||
|
|
||||||
waitjob:
|
|
||||||
/* If we have made changes to XML due to a copy job, make a best
|
/* If we have made changes to XML due to a copy job, make a best
|
||||||
* effort to save it now. But we can ignore failure, since there
|
* effort to save it now. But we can ignore failure, since there
|
||||||
* will be further changes when the event marks completion. */
|
* will be further changes when the event marks completion. */
|
||||||
@ -16450,33 +16445,37 @@ qemuDomainBlockJobAbort(virDomainPtr dom,
|
|||||||
* while still holding the VM job, to prevent newly scheduled
|
* while still holding the VM job, to prevent newly scheduled
|
||||||
* block jobs from confusing us. */
|
* block jobs from confusing us. */
|
||||||
if (!async) {
|
if (!async) {
|
||||||
/* Older qemu that lacked async reporting also lacked
|
if (!modern) {
|
||||||
* blockcopy and active commit, so we can hardcode the
|
/* Older qemu that lacked async reporting also lacked
|
||||||
* event to pull, and we know the XML doesn't need
|
* blockcopy and active commit, so we can hardcode the
|
||||||
* updating. We have to generate two event variants. */
|
* event to pull and let qemuBlockJobEventProcess() handle
|
||||||
int type = VIR_DOMAIN_BLOCK_JOB_TYPE_PULL;
|
* the rest as usual */
|
||||||
int status = VIR_DOMAIN_BLOCK_JOB_CANCELED;
|
disk->blockJobType = VIR_DOMAIN_BLOCK_JOB_TYPE_PULL;
|
||||||
event = virDomainEventBlockJobNewFromObj(vm, disk->src->path, type,
|
disk->blockJobStatus = VIR_DOMAIN_BLOCK_JOB_CANCELED;
|
||||||
status);
|
} else {
|
||||||
event2 = virDomainEventBlockJob2NewFromObj(vm, disk->dst, type,
|
while (disk->blockJobStatus == -1 && disk->blockJobSync) {
|
||||||
status);
|
if (virCondWait(&disk->blockJobSyncCond, &vm->parent.lock) < 0) {
|
||||||
} else if (disk->blockJobSync) {
|
virReportSystemError(errno, "%s",
|
||||||
/* XXX If the event reports failure, we should reflect
|
_("Unable to wait on block job sync "
|
||||||
* that back into the return status of this API call. */
|
"condition"));
|
||||||
|
disk->blockJobSync = false;
|
||||||
while (disk->blockJobStatus == -1 && disk->blockJobSync) {
|
goto endjob;
|
||||||
if (virCondWait(&disk->blockJobSyncCond, &vm->parent.lock) < 0) {
|
}
|
||||||
virReportSystemError(errno, "%s",
|
|
||||||
_("Unable to wait on block job sync "
|
|
||||||
"condition"));
|
|
||||||
disk->blockJobSync = false;
|
|
||||||
goto endjob;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qemuBlockJobEventProcess(driver, vm, disk,
|
qemuBlockJobEventProcess(driver, vm, disk,
|
||||||
disk->blockJobType,
|
disk->blockJobType,
|
||||||
disk->blockJobStatus);
|
disk->blockJobStatus);
|
||||||
|
|
||||||
|
/* adjust the return code if we've got an explicit failure */
|
||||||
|
if (disk->blockJobStatus == VIR_DOMAIN_BLOCK_JOB_FAILED) {
|
||||||
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
||||||
|
_("failed to terminate block job on disk '%s'"),
|
||||||
|
disk->dst);
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
disk->blockJobSync = false;
|
disk->blockJobSync = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16487,10 +16486,6 @@ qemuDomainBlockJobAbort(virDomainPtr dom,
|
|||||||
virObjectUnref(cfg);
|
virObjectUnref(cfg);
|
||||||
VIR_FREE(device);
|
VIR_FREE(device);
|
||||||
qemuDomObjEndAPI(&vm);
|
qemuDomObjEndAPI(&vm);
|
||||||
if (event)
|
|
||||||
qemuDomainEventQueue(driver, event);
|
|
||||||
if (event2)
|
|
||||||
qemuDomainEventQueue(driver, event2);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user