提交 634285f9 编写于 作者: P Peter Krempa

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.
上级 8a609afb
...@@ -16355,13 +16355,13 @@ qemuDomainBlockJobAbort(virDomainPtr dom, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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); qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorBlockJobCancel(qemuDomainGetMonitor(vm), device, async); ret = qemuMonitorBlockJobCancel(qemuDomainGetMonitor(vm), device, modern);
if (qemuDomainObjExitMonitor(driver, vm) < 0) if (qemuDomainObjExitMonitor(driver, vm) < 0) {
ret = -1; ret = -1;
goto endjob;
}
if (ret < 0) { if (ret < 0) {
if (disk->mirror) if (disk->mirror)
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE; disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
goto endjob; 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, ...@@ -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, ...@@ -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;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册