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 <pkrempa@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2019-10-16 09:39:32 +02:00
parent 9ac4b7db8d
commit 2c59f0083e
3 changed files with 72 additions and 0 deletions

View File

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

View File

@ -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);

View File

@ -2608,6 +2608,18 @@ qemuDomainObjPrivateXMLFormatBlockjobIterator(void *payload,
break;
case QEMU_BLOCKJOB_TYPE_BACKUP:
virBufferEscapeString(&childBuf, "<bitmap name='%s'/>\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, "<deleteStore/>\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: