|
|
7a3408 |
From 14b6b01cce6316d9df09f473592de303dce94084 Mon Sep 17 00:00:00 2001
|
|
|
7a3408 |
Message-Id: <14b6b01cce6316d9df09f473592de303dce94084@dist-git>
|
|
|
7a3408 |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
7a3408 |
Date: Tue, 21 Jul 2015 16:18:32 +0200
|
|
|
7a3408 |
Subject: [PATCH] qemu: Update state of block job to READY only if it actually
|
|
|
7a3408 |
is ready
|
|
|
7a3408 |
|
|
|
7a3408 |
https://bugzilla.redhat.com/show_bug.cgi?id=1227551
|
|
|
7a3408 |
https://bugzilla.redhat.com/show_bug.cgi?id=1197592
|
|
|
7a3408 |
|
|
|
7a3408 |
Few parts of the code looked at the current progress of and assumed that
|
|
|
7a3408 |
a two phase blockjob is in the _READY state as soon as the progress
|
|
|
7a3408 |
reached 100% (info.cur == info.end). In current versions of qemu this
|
|
|
7a3408 |
assumption is invalid and qemu exposes a new flag 'ready' in the
|
|
|
7a3408 |
query-block-jobs output that is set to true if the job is actually
|
|
|
7a3408 |
finished.
|
|
|
7a3408 |
|
|
|
7a3408 |
This patch adds internal data handling for reading the 'ready' flag and
|
|
|
7a3408 |
acting appropriately as long as the flag is present.
|
|
|
7a3408 |
|
|
|
7a3408 |
While this still doesn't fix the virsh client problem with two phase
|
|
|
7a3408 |
block jobs and the --pivot option, it at least improves the error
|
|
|
7a3408 |
message:
|
|
|
7a3408 |
|
|
|
7a3408 |
$ virsh blockcommit --wait --verbose vm vda --base vda[1] --active --pivot
|
|
|
7a3408 |
Block commit: [100 %]error: failed to pivot job for disk vda
|
|
|
7a3408 |
error: internal error: unable to execute QEMU command 'block-job-complete': The active block job for device 'drive-virtio-disk0' cannot be completed
|
|
|
7a3408 |
|
|
|
7a3408 |
to
|
|
|
7a3408 |
|
|
|
7a3408 |
$ virsh blockcommit --wait --verbose VM vda --base vda[1] --active --pivot
|
|
|
7a3408 |
Block commit: [100 %]error: failed to pivot job for disk vda
|
|
|
7a3408 |
error: block copy still active: disk 'vda' not ready for pivot yet
|
|
|
7a3408 |
|
|
|
7a3408 |
(cherry picked from commit eae59247c59aa02147b2b4a50177e8e877fdb218)
|
|
|
7a3408 |
|
|
|
7a3408 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
7a3408 |
---
|
|
|
7a3408 |
src/qemu/qemu_driver.c | 10 ++++++++--
|
|
|
7a3408 |
src/qemu/qemu_monitor.h | 1 +
|
|
|
7a3408 |
src/qemu/qemu_monitor_json.c | 7 +++++++
|
|
|
7a3408 |
3 files changed, 16 insertions(+), 2 deletions(-)
|
|
|
7a3408 |
|
|
|
7a3408 |
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|
|
7a3408 |
index 47889d9..204ed72 100644
|
|
|
7a3408 |
--- a/src/qemu/qemu_driver.c
|
|
|
7a3408 |
+++ b/src/qemu/qemu_driver.c
|
|
|
7a3408 |
@@ -16170,8 +16170,12 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
|
|
|
7a3408 |
goto cleanup;
|
|
|
7a3408 |
if (rc < 0)
|
|
|
7a3408 |
goto cleanup;
|
|
|
7a3408 |
- if (rc == 1 && info.cur == info.end &&
|
|
|
7a3408 |
- info.type == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY)
|
|
|
7a3408 |
+ if (rc == 1 &&
|
|
|
7a3408 |
+ (info.ready == 1 ||
|
|
|
7a3408 |
+ (info.ready == -1 &&
|
|
|
7a3408 |
+ info.end == info.cur &&
|
|
|
7a3408 |
+ (info.type == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY ||
|
|
|
7a3408 |
+ info.type == VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT))))
|
|
|
7a3408 |
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_READY;
|
|
|
7a3408 |
}
|
|
|
7a3408 |
|
|
|
7a3408 |
@@ -16569,6 +16573,7 @@ qemuDomainGetBlockJobInfo(virDomainPtr dom,
|
|
|
7a3408 |
* hold the vm lock, so modifying the in-memory representation is
|
|
|
7a3408 |
* safe, even if we are a query rather than a modify job. */
|
|
|
7a3408 |
if (ret == 1 && disk->mirror &&
|
|
|
7a3408 |
+ rawInfo.ready != 0 &&
|
|
|
7a3408 |
info->cur == info->end && !disk->mirrorState) {
|
|
|
7a3408 |
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
|
|
7a3408 |
|
|
|
7a3408 |
@@ -17199,6 +17204,7 @@ qemuDomainBlockCommit(virDomainPtr dom,
|
|
|
7a3408 |
* thing if the user specified a relative name). Be prepared for
|
|
|
7a3408 |
* a ready event to occur while locks are dropped. */
|
|
|
7a3408 |
if (mirror) {
|
|
|
7a3408 |
+ disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
|
|
|
7a3408 |
disk->mirror = mirror;
|
|
|
7a3408 |
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT;
|
|
|
7a3408 |
}
|
|
|
7a3408 |
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
|
|
|
7a3408 |
index 8ad3b2b..fc58638 100644
|
|
|
7a3408 |
--- a/src/qemu/qemu_monitor.h
|
|
|
7a3408 |
+++ b/src/qemu/qemu_monitor.h
|
|
|
7a3408 |
@@ -798,6 +798,7 @@ struct _qemuMonitorBlockJobInfo {
|
|
|
7a3408 |
unsigned long long bandwidth; /* in bytes/s */
|
|
|
7a3408 |
virDomainBlockJobCursor cur;
|
|
|
7a3408 |
virDomainBlockJobCursor end;
|
|
|
7a3408 |
+ int ready; /* -1 if unknown, 0 if not ready, 1 if ready */
|
|
|
7a3408 |
};
|
|
|
7a3408 |
|
|
|
7a3408 |
virHashTablePtr qemuMonitorGetAllBlockJobInfo(qemuMonitorPtr mon);
|
|
|
7a3408 |
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
|
|
|
7a3408 |
index 4040ff0..d2a5374 100644
|
|
|
7a3408 |
--- a/src/qemu/qemu_monitor_json.c
|
|
|
7a3408 |
+++ b/src/qemu/qemu_monitor_json.c
|
|
|
7a3408 |
@@ -4136,6 +4136,7 @@ qemuMonitorJSONParseBlockJobInfo(virHashTablePtr blockJobs,
|
|
|
7a3408 |
qemuMonitorBlockJobInfoPtr info = NULL;
|
|
|
7a3408 |
const char *device;
|
|
|
7a3408 |
const char *type;
|
|
|
7a3408 |
+ bool ready;
|
|
|
7a3408 |
|
|
|
7a3408 |
if (!(device = virJSONValueObjectGetString(entry, "device"))) {
|
|
|
7a3408 |
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
7a3408 |
@@ -4151,6 +4152,9 @@ qemuMonitorJSONParseBlockJobInfo(virHashTablePtr blockJobs,
|
|
|
7a3408 |
return -1;
|
|
|
7a3408 |
}
|
|
|
7a3408 |
|
|
|
7a3408 |
+ /* assume we don't know the state */
|
|
|
7a3408 |
+ info->ready = -1;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
if (!(type = virJSONValueObjectGetString(entry, "type"))) {
|
|
|
7a3408 |
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
7a3408 |
_("entry was missing 'type'"));
|
|
|
7a3408 |
@@ -4183,6 +4187,9 @@ qemuMonitorJSONParseBlockJobInfo(virHashTablePtr blockJobs,
|
|
|
7a3408 |
return -1;
|
|
|
7a3408 |
}
|
|
|
7a3408 |
|
|
|
7a3408 |
+ if (virJSONValueObjectGetBoolean(entry, "ready", &ready) == 0)
|
|
|
7a3408 |
+ info->ready = ready;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
return 0;
|
|
|
7a3408 |
}
|
|
|
7a3408 |
|
|
|
7a3408 |
--
|
|
|
7a3408 |
2.5.0
|
|
|
7a3408 |
|