提交 dae7d013 编写于 作者: P Peter Krempa

qemu: blockjob: Register disk->mirror with a job only when required

The <mirror> subelement is used in two ways: in a commit job to point to
existing storage, and in a block-copy job to point to additional
storage. We need a way to track only the distinct storage.

This patch introduces qemuBlockJobDiskRegisterMirror which registers the
mirror chain separately only for jobs which require it. This also comes
with remembering that in the status XML.
Signed-off-by: NPeter Krempa <pkrempa@redhat.com>
ACKed-by: NEric Blake <eblake@redhat.com>
上级 35a97e45
......@@ -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
......
......@@ -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);
......
......@@ -2367,7 +2367,10 @@ qemuDomainObjPrivateXMLFormatBlockjobIterator(void *payload,
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,
......@@ -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;
......
......@@ -235,7 +235,7 @@
<nodename index='0'/>
<blockjobs active='yes'>
<blockjob name='drive-virtio-disk0' type='copy' state='ready'>
<disk dst='vda'/>
<disk dst='vda' mirror='yes'/>
</blockjob>
<blockjob name='test-orphan-job0' type='copy' state='ready'>
<chains>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册