diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index 46f0318207..fa82e49b71 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -9896,6 +9896,13 @@ virDomainBlockJobAbort(virDomainPtr dom, const char *disk, * can be found by calling virDomainGetXMLDesc() and inspecting * elements within //domain/devices/disk. * + * As a corner case underlying hypervisor may report cur == 0 and + * end == 0 when the block job hasn't been started yet. In this + * case libvirt reports cur = 0 and end = 1. However, hypervisor + * may return cur == 0 and end == 0 if the block job has finished + * and was no-op. In this case libvirt reports cur = 1 and end = 1. + * Since 2.3.0. + * * Returns -1 in case of failure, 0 when nothing found, 1 when info was found. */ int diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 6b3a35540a..e29180da4e 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -16318,6 +16318,18 @@ qemuBlockJobInfoTranslate(qemuMonitorBlockJobInfoPtr rawInfo, info->cur = rawInfo->cur; info->end = rawInfo->end; + /* Fix job completeness reporting. If cur == end mgmt + * applications think job is completed. Except when both cur + * and end are zero, in which case qemu hasn't started the + * job yet. */ + if (!info->cur && !info->end) { + if (rawInfo->ready > 0) { + info->cur = info->end = 1; + } else if (!rawInfo->ready) { + info->end = 1; + } + } + info->type = rawInfo->type; if (info->type == VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT && disk->mirrorJob == VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT)