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 @@ - +