From: Peter Krempa Date: Wed, 16 Oct 2019 07:39:32 +0000 (+0200) Subject: qemu: blockjob: Track internal data for 'backup' blockjob X-Git-Tag: v6.0.0-rc1~410 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2c59f0083e994fb44e8236b51511754ead2d7f33;p=thirdparty%2Flibvirt.git qemu: blockjob: Track internal data for 'backup' blockjob A backup blockjob needs to be able to notify the parent backup job as well as track all data to be able to clean up the bitmap and blockdev used for the backup. Add the data structure, job allocation function and status XML formatter and parser. Signed-off-by: Peter Krempa Reviewed-by: Daniel P. Berrangé Reviewed-by: Eric Blake Reviewed-by: Ján Tomko --- diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index ce4056a7b3..b17577e987 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -78,6 +78,11 @@ qemuBlockJobDataDisposeJobdata(qemuBlockJobDataPtr job) { if (job->type == QEMU_BLOCKJOB_TYPE_CREATE) virObjectUnref(job->data.create.src); + + if (job->type == QEMU_BLOCKJOB_TYPE_BACKUP) { + virObjectUnref(job->data.backup.store); + g_free(job->data.backup.bitmap); + } } @@ -370,6 +375,34 @@ qemuBlockJobDiskNewCopy(virDomainObjPtr vm, } +qemuBlockJobDataPtr +qemuBlockJobDiskNewBackup(virDomainObjPtr vm, + virDomainDiskDefPtr disk, + virStorageSourcePtr store, + bool deleteStore, + const char *bitmap) +{ + g_autoptr(qemuBlockJobData) job = NULL; + g_autofree char *jobname = NULL; + + jobname = g_strdup_printf("backup-%s-%s", disk->dst, disk->src->nodeformat); + + if (!(job = qemuBlockJobDataNew(QEMU_BLOCKJOB_TYPE_BACKUP, jobname))) + return NULL; + + job->data.backup.bitmap = g_strdup(bitmap); + job->data.backup.store = virObjectRef(store); + job->data.backup.deleteStore = deleteStore; + + /* backup jobs are usually started in bulk by transaction so the caller + * shall save the status XML */ + if (qemuBlockJobRegister(job, vm, disk, false) < 0) + return NULL; + + return g_steal_pointer(&job); +} + + /** * qemuBlockJobDiskGetJob: * @disk: disk definition diff --git a/src/qemu/qemu_blockjob.h b/src/qemu/qemu_blockjob.h index 4734984c99..52b03aaf9e 100644 --- a/src/qemu/qemu_blockjob.h +++ b/src/qemu/qemu_blockjob.h @@ -107,6 +107,16 @@ struct _qemuBlockJobCopyData { }; +typedef struct _qemuBlockJobBackupData qemuBlockJobBackupData; +typedef qemuBlockJobBackupData *qemuBlockJobDataBackupPtr; + +struct _qemuBlockJobBackupData { + virStorageSourcePtr store; + bool deleteStore; + char *bitmap; +}; + + typedef struct _qemuBlockJobData qemuBlockJobData; typedef qemuBlockJobData *qemuBlockJobDataPtr; @@ -124,6 +134,7 @@ struct _qemuBlockJobData { qemuBlockJobCommitData commit; qemuBlockJobCreateData create; qemuBlockJobCopyData copy; + qemuBlockJobBackupData backup; } data; int type; /* qemuBlockJobType */ @@ -184,6 +195,13 @@ qemuBlockJobDiskNewCopy(virDomainObjPtr vm, bool shallow, bool reuse); +qemuBlockJobDataPtr +qemuBlockJobDiskNewBackup(virDomainObjPtr vm, + virDomainDiskDefPtr disk, + virStorageSourcePtr store, + bool deleteStore, + const char *bitmap); + qemuBlockJobDataPtr qemuBlockJobDiskGetJob(virDomainDiskDefPtr disk) ATTRIBUTE_NONNULL(1); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 1be6cfccff..873a397ac6 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2608,6 +2608,18 @@ qemuDomainObjPrivateXMLFormatBlockjobIterator(void *payload, break; case QEMU_BLOCKJOB_TYPE_BACKUP: + virBufferEscapeString(&childBuf, "\n", job->data.backup.bitmap); + if (job->data.backup.store) { + if (qemuDomainObjPrivateXMLFormatBlockjobFormatSource(&childBuf, + "store", + job->data.backup.store, + data->xmlopt, + false) < 0) + return -1; + + if (job->data.backup.deleteStore) + virBufferAddLit(&childBuf, "\n"); + } break; case QEMU_BLOCKJOB_TYPE_BROKEN: @@ -3202,6 +3214,15 @@ qemuDomainObjPrivateXMLParseBlockjobDataSpecific(qemuBlockJobDataPtr job, break; case QEMU_BLOCKJOB_TYPE_BACKUP: + job->data.backup.bitmap = virXPathString("string(./bitmap/@name)", ctxt); + + if (!(tmp = virXPathNode("./store", ctxt)) || + !(job->data.backup.store = qemuDomainObjPrivateXMLParseBlockjobChain(tmp, ctxt, xmlopt))) + goto broken; + + if (virXPathNode("./deleteStore", ctxt)) + job->data.backup.deleteStore = true; + break; case QEMU_BLOCKJOB_TYPE_BROKEN: