*
* 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,
if (disk) {
job->disk = disk;
job->chain = virObjectRef(disk->src);
- job->mirrorChain = virObjectRef(disk->mirror);
QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob = virObjectRef(job);
}
}
+/**
+ * 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
virBufferEscapeString(&childBuf, "<errmsg>%s</errmsg>", job->errmsg);
if (job->disk) {
- virBufferEscapeString(&childBuf, "<disk dst='%s'/>\n", job->disk->dst);
+ virBufferEscapeString(&childBuf, "<disk dst='%s'", job->disk->dst);
+ if (job->mirrorChain)
+ virBufferAddLit(&childBuf, " mirror='yes'");
+ virBufferAddLit(&childBuf, "/>\n");
} else {
if (job->chain &&
qemuDomainObjPrivateXMLFormatBlockjobFormatChain(&chainsBuf,
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;
!(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)))
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;