diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 9dbe6355b7..61a7a7cc2c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -16091,8 +16091,12 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver, goto cleanup; if (rc < 0) goto cleanup; - if (rc == 1 && info.cur == info.end && - info.type == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY) + if (rc == 1 && + (info.ready == 1 || + (info.ready == -1 && + info.end == info.cur && + (info.type == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY || + info.type == VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT)))) disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_READY; } @@ -16490,6 +16494,7 @@ qemuDomainGetBlockJobInfo(virDomainPtr dom, * hold the vm lock, so modifying the in-memory representation is * safe, even if we are a query rather than a modify job. */ if (ret == 1 && disk->mirror && + rawInfo.ready != 0 && info->cur == info->end && !disk->mirrorState) { virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); @@ -17120,6 +17125,7 @@ qemuDomainBlockCommit(virDomainPtr dom, * thing if the user specified a relative name). Be prepared for * a ready event to occur while locks are dropped. */ if (mirror) { + disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE; disk->mirror = mirror; disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT; } diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 1e7b6bb787..85ea8222f0 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -797,6 +797,7 @@ struct _qemuMonitorBlockJobInfo { unsigned long long bandwidth; /* in bytes/s */ virDomainBlockJobCursor cur; virDomainBlockJobCursor end; + int ready; /* -1 if unknown, 0 if not ready, 1 if ready */ }; virHashTablePtr qemuMonitorGetAllBlockJobInfo(qemuMonitorPtr mon); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index ff568d9204..5c2f50ffaa 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -4027,6 +4027,7 @@ qemuMonitorJSONParseBlockJobInfo(virHashTablePtr blockJobs, qemuMonitorBlockJobInfoPtr info = NULL; const char *device; const char *type; + bool ready; if (!(device = virJSONValueObjectGetString(entry, "device"))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -4042,6 +4043,9 @@ qemuMonitorJSONParseBlockJobInfo(virHashTablePtr blockJobs, return -1; } + /* assume we don't know the state */ + info->ready = -1; + if (!(type = virJSONValueObjectGetString(entry, "type"))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("entry was missing 'type'")); @@ -4074,6 +4078,9 @@ qemuMonitorJSONParseBlockJobInfo(virHashTablePtr blockJobs, return -1; } + if (virJSONValueObjectGetBoolean(entry, "ready", &ready) == 0) + info->ready = ready; + return 0; }