diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
index ac7b3a0aef520a07c669511449550b7062d41f3c..52065f07caa953873a22925041cce40ebf8d25d9 100644
--- a/src/qemu/qemu_blockjob.c
+++ b/src/qemu/qemu_blockjob.c
@@ -126,6 +126,9 @@ qemuBlockJobDataNew(qemuBlockJobType type,
*
* This function registers @job with @disk and @vm and records it into the status
* xml (if @savestatus is true).
+ *
+ * Note that if @job also references a separate chain e.g. for disk mirroring,
+ * then qemuBlockJobDiskRegisterMirror should be used separately.
*/
int
qemuBlockJobRegister(qemuBlockJobDataPtr job,
@@ -143,7 +146,6 @@ qemuBlockJobRegister(qemuBlockJobDataPtr job,
if (disk) {
job->disk = disk;
job->chain = virObjectRef(disk->src);
- job->mirrorChain = virObjectRef(disk->mirror);
QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob = virObjectRef(job);
}
@@ -205,6 +207,24 @@ qemuBlockJobDiskNew(virDomainObjPtr vm,
}
+/**
+ * qemuBlockJobDiskRegisterMirror:
+ * @job: block job to register 'mirror' chain on
+ *
+ * In cases when the disk->mirror attribute references a separate storage chain
+ * such as for block-copy, this function registers it with the job. Note
+ * that this function does not save the status XML and thus must be used before
+ * qemuBlockJobRegister or qemuBlockJobStarted to properly track the chain
+ * in the status XML.
+ */
+void
+qemuBlockJobDiskRegisterMirror(qemuBlockJobDataPtr job)
+{
+ if (job->disk)
+ job->mirrorChain = virObjectRef(job->disk->mirror);
+}
+
+
/**
* qemuBlockJobDiskGetJob:
* @disk: disk definition
diff --git a/src/qemu/qemu_blockjob.h b/src/qemu/qemu_blockjob.h
index 47bdc54b2b81f43904f2fa459964c81865fe353b..3299207610c419d628e5ad8852dccece1c9cae14 100644
--- a/src/qemu/qemu_blockjob.h
+++ b/src/qemu/qemu_blockjob.h
@@ -110,6 +110,10 @@ qemuBlockJobDiskNew(virDomainObjPtr vm,
const char *jobname)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4);
+void
+qemuBlockJobDiskRegisterMirror(qemuBlockJobDataPtr job)
+ ATTRIBUTE_NONNULL(1);
+
qemuBlockJobDataPtr
qemuBlockJobDiskGetJob(virDomainDiskDefPtr disk)
ATTRIBUTE_NONNULL(1);
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index e7f28aa2b87881718e7504a2b2ca8bece5f2fe93..c508f5528748923324826bc9f6ab3e358be770fd 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2367,7 +2367,10 @@ qemuDomainObjPrivateXMLFormatBlockjobIterator(void *payload,
virBufferEscapeString(&childBuf, "%s", job->errmsg);
if (job->disk) {
- virBufferEscapeString(&childBuf, "\n", job->disk->dst);
+ virBufferEscapeString(&childBuf, "disk->dst);
+ if (job->mirrorChain)
+ virBufferAddLit(&childBuf, " mirror='yes'");
+ virBufferAddLit(&childBuf, "/>\n");
} else {
if (job->chain &&
qemuDomainObjPrivateXMLFormatBlockjobFormatChain(&chainsBuf,
@@ -2806,6 +2809,7 @@ qemuDomainObjPrivateXMLParseBlockjobData(virDomainObjPtr vm,
int state = QEMU_BLOCKJOB_STATE_FAILED;
VIR_AUTOFREE(char *) diskdst = NULL;
VIR_AUTOFREE(char *) newstatestr = NULL;
+ VIR_AUTOFREE(char *) mirror = NULL;
int newstate = -1;
bool invalidData = false;
xmlNodePtr tmp;
@@ -2840,6 +2844,10 @@ qemuDomainObjPrivateXMLParseBlockjobData(virDomainObjPtr vm,
!(disk = virDomainDiskByName(vm->def, diskdst, false)))
invalidData = true;
+ if ((mirror = virXPathString("string(./disk/@mirror)", ctxt)) &&
+ STRNEQ(mirror, "yes"))
+ invalidData = true;
+
if (!disk && !invalidData) {
if ((tmp = virXPathNode("./chains/disk", ctxt)) &&
!(job->chain = qemuDomainObjPrivateXMLParseBlockjobChain(tmp, ctxt, xmlopt)))
@@ -2854,6 +2862,10 @@ qemuDomainObjPrivateXMLParseBlockjobData(virDomainObjPtr vm,
job->newstate = newstate;
job->errmsg = virXPathString("string(./errmsg)", ctxt);
job->invalidData = invalidData;
+ job->disk = disk;
+
+ if (mirror)
+ qemuBlockJobDiskRegisterMirror(job);
if (qemuBlockJobRegister(job, vm, disk, false) < 0)
return -1;
diff --git a/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml b/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml
index 5b9777ca7181477b3a19ac3d9b7a795bbd84f03d..7b9282d059504186b9ed70f4508bcfb831b7c811 100644
--- a/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml
+++ b/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml
@@ -235,7 +235,7 @@
-
+