On 07/29/2014 05:40 AM, Peter Krempa wrote:
> Fix things by saving state any time we modify live XML, while
> delaying XML disk modifications until after the event completes. We
> still need a to teach libvirtd restarts to examine all existing
> <mirror> elements to see if the job completed in the meantime (that
> is, if libvirtd misses the event, the updated state still needs to be
> updated in live XML), but that will be a later patch, in part because
> we also need to to start taking advantage of newer qemu's ability to
> keep the job around after completion rather than the current usage
> where the job disappears both on error and on success.
>
> + /* If we completed a block pull or commit, then update
the XML
> + * to match. */
> + if (status == VIR_DOMAIN_BLOCK_JOB_COMPLETED) {
> + bool has_mirror = !!disk->mirror;
The control flow is becoming less obvious in this function.
Yeah, I struggled on that for a while.
> +
> + if (disk->mirrorState == VIR_DOMAIN_DISK_MIRROR_PIVOT) {
> + /* XXX We want to revoke security labels and disk
> + * lease, as well as audit that revocation, before
> + * dropping the original source. But it gets tricky
> + * if both source and mirror share common backing
> + * files (we want to only revoke the non-shared
> + * portion of the chain); so for now, we leak the
> + * access to the original. */
> + virStorageSourceFree(disk->src);
> + disk->src = disk->mirror;
> + disk->mirror = NULL;
If we were here, then
> + }
> + if (has_mirror) {
This condition is also true and we try to free the source of the mirror
again, even if we did it above. On the other hand, this is reached even
if the _ABORT job is completed, where this makes sense.
Basically, once a job completes, we have to clean up disk->mirror
whether it was abort or pivot; but if it was pivot, we also have to
adjust the source to be the former mirror contents. But I agree that a
minor tweak to the flow makes it easier to read.
> qemuDomainDetermineDiskChain(driver, vm, disk,
true);
> - if (disk->mirror && type == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY) {
> + }
> +
> + if (disk->mirror &&
Now this really is an else section to the above as both paths above
clear disk->mirror.
Also correct.
ACK, the function flow isn't obvious but it's correct from my POV
After rebasing on top of 1/4, here's what I squashed in to improve the
control flow, before pushing 1 and 2. I'll wait on 3 and 4 for any
other opinions on whether active commit deserves to be in rc2.
diff --git i/src/qemu/qemu_process.c w/src/qemu/qemu_process.c
index 1340c8d..48da843 100644
--- i/src/qemu/qemu_process.c
+++ w/src/qemu/qemu_process.c
@@ -1033,8 +1033,6 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon
ATTRIBUTE_UNUSED,
/* If we completed a block pull or commit, then update the XML
* to match. */
if (status == VIR_DOMAIN_BLOCK_JOB_COMPLETED) {
- bool has_mirror = !!disk->mirror;
-
if (disk->mirrorState == VIR_DOMAIN_DISK_MIRROR_STATE_PIVOT) {
/* XXX We want to revoke security labels and disk
* lease, as well as audit that revocation, before
@@ -1045,22 +1043,19 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon
ATTRIBUTE_UNUSED,
* access to the original. */
virStorageSourceFree(disk->src);
disk->src = disk->mirror;
- disk->mirror = NULL;
- }
- if (has_mirror) {
+ } else {
virStorageSourceFree(disk->mirror);
- disk->mirror = NULL;
- save = disk->mirrorState !=
VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
- disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
}
+
/* Recompute the cached backing chain to match our
* updates. Better would be storing the chain ourselves
* rather than reprobing, but we haven't quite completed
* that conversion to use our XML tracking. */
+ disk->mirror = NULL;
+ save = disk->mirrorState != VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
+ disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
qemuDomainDetermineDiskChain(driver, vm, disk, true);
- }
-
- if (disk->mirror && type == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY) {
+ } else if (disk->mirror && type ==
VIR_DOMAIN_BLOCK_JOB_TYPE_COPY) {
if (status == VIR_DOMAIN_BLOCK_JOB_READY) {
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_READY;
save = true;
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library
http://libvirt.org