mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 11:35:19 +00:00
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: Peter Krempa <pkrempa@redhat.com> ACKed-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
35a97e4532
commit
dae7d01322
@ -126,6 +126,9 @@ qemuBlockJobDataNew(qemuBlockJobType type,
|
|||||||
*
|
*
|
||||||
* This function registers @job with @disk and @vm and records it into the status
|
* This function registers @job with @disk and @vm and records it into the status
|
||||||
* xml (if @savestatus is true).
|
* 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
|
int
|
||||||
qemuBlockJobRegister(qemuBlockJobDataPtr job,
|
qemuBlockJobRegister(qemuBlockJobDataPtr job,
|
||||||
@ -143,7 +146,6 @@ qemuBlockJobRegister(qemuBlockJobDataPtr job,
|
|||||||
if (disk) {
|
if (disk) {
|
||||||
job->disk = disk;
|
job->disk = disk;
|
||||||
job->chain = virObjectRef(disk->src);
|
job->chain = virObjectRef(disk->src);
|
||||||
job->mirrorChain = virObjectRef(disk->mirror);
|
|
||||||
QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob = virObjectRef(job);
|
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:
|
* qemuBlockJobDiskGetJob:
|
||||||
* @disk: disk definition
|
* @disk: disk definition
|
||||||
|
@ -110,6 +110,10 @@ qemuBlockJobDiskNew(virDomainObjPtr vm,
|
|||||||
const char *jobname)
|
const char *jobname)
|
||||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4);
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4);
|
||||||
|
|
||||||
|
void
|
||||||
|
qemuBlockJobDiskRegisterMirror(qemuBlockJobDataPtr job)
|
||||||
|
ATTRIBUTE_NONNULL(1);
|
||||||
|
|
||||||
qemuBlockJobDataPtr
|
qemuBlockJobDataPtr
|
||||||
qemuBlockJobDiskGetJob(virDomainDiskDefPtr disk)
|
qemuBlockJobDiskGetJob(virDomainDiskDefPtr disk)
|
||||||
ATTRIBUTE_NONNULL(1);
|
ATTRIBUTE_NONNULL(1);
|
||||||
|
@ -2367,7 +2367,10 @@ qemuDomainObjPrivateXMLFormatBlockjobIterator(void *payload,
|
|||||||
virBufferEscapeString(&childBuf, "<errmsg>%s</errmsg>", job->errmsg);
|
virBufferEscapeString(&childBuf, "<errmsg>%s</errmsg>", job->errmsg);
|
||||||
|
|
||||||
if (job->disk) {
|
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 {
|
} else {
|
||||||
if (job->chain &&
|
if (job->chain &&
|
||||||
qemuDomainObjPrivateXMLFormatBlockjobFormatChain(&chainsBuf,
|
qemuDomainObjPrivateXMLFormatBlockjobFormatChain(&chainsBuf,
|
||||||
@ -2806,6 +2809,7 @@ qemuDomainObjPrivateXMLParseBlockjobData(virDomainObjPtr vm,
|
|||||||
int state = QEMU_BLOCKJOB_STATE_FAILED;
|
int state = QEMU_BLOCKJOB_STATE_FAILED;
|
||||||
VIR_AUTOFREE(char *) diskdst = NULL;
|
VIR_AUTOFREE(char *) diskdst = NULL;
|
||||||
VIR_AUTOFREE(char *) newstatestr = NULL;
|
VIR_AUTOFREE(char *) newstatestr = NULL;
|
||||||
|
VIR_AUTOFREE(char *) mirror = NULL;
|
||||||
int newstate = -1;
|
int newstate = -1;
|
||||||
bool invalidData = false;
|
bool invalidData = false;
|
||||||
xmlNodePtr tmp;
|
xmlNodePtr tmp;
|
||||||
@ -2840,6 +2844,10 @@ qemuDomainObjPrivateXMLParseBlockjobData(virDomainObjPtr vm,
|
|||||||
!(disk = virDomainDiskByName(vm->def, diskdst, false)))
|
!(disk = virDomainDiskByName(vm->def, diskdst, false)))
|
||||||
invalidData = true;
|
invalidData = true;
|
||||||
|
|
||||||
|
if ((mirror = virXPathString("string(./disk/@mirror)", ctxt)) &&
|
||||||
|
STRNEQ(mirror, "yes"))
|
||||||
|
invalidData = true;
|
||||||
|
|
||||||
if (!disk && !invalidData) {
|
if (!disk && !invalidData) {
|
||||||
if ((tmp = virXPathNode("./chains/disk", ctxt)) &&
|
if ((tmp = virXPathNode("./chains/disk", ctxt)) &&
|
||||||
!(job->chain = qemuDomainObjPrivateXMLParseBlockjobChain(tmp, ctxt, xmlopt)))
|
!(job->chain = qemuDomainObjPrivateXMLParseBlockjobChain(tmp, ctxt, xmlopt)))
|
||||||
@ -2854,6 +2862,10 @@ qemuDomainObjPrivateXMLParseBlockjobData(virDomainObjPtr vm,
|
|||||||
job->newstate = newstate;
|
job->newstate = newstate;
|
||||||
job->errmsg = virXPathString("string(./errmsg)", ctxt);
|
job->errmsg = virXPathString("string(./errmsg)", ctxt);
|
||||||
job->invalidData = invalidData;
|
job->invalidData = invalidData;
|
||||||
|
job->disk = disk;
|
||||||
|
|
||||||
|
if (mirror)
|
||||||
|
qemuBlockJobDiskRegisterMirror(job);
|
||||||
|
|
||||||
if (qemuBlockJobRegister(job, vm, disk, false) < 0)
|
if (qemuBlockJobRegister(job, vm, disk, false) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -235,7 +235,7 @@
|
|||||||
<nodename index='0'/>
|
<nodename index='0'/>
|
||||||
<blockjobs active='yes'>
|
<blockjobs active='yes'>
|
||||||
<blockjob name='drive-virtio-disk0' type='copy' state='ready'>
|
<blockjob name='drive-virtio-disk0' type='copy' state='ready'>
|
||||||
<disk dst='vda'/>
|
<disk dst='vda' mirror='yes'/>
|
||||||
</blockjob>
|
</blockjob>
|
||||||
<blockjob name='test-orphan-job0' type='copy' state='ready'>
|
<blockjob name='test-orphan-job0' type='copy' state='ready'>
|
||||||
<chains>
|
<chains>
|
||||||
|
Loading…
Reference in New Issue
Block a user