]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: blockjob: Track internal data for 'backup' blockjob
authorPeter Krempa <pkrempa@redhat.com>
Wed, 16 Oct 2019 07:39:32 +0000 (09:39 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 10 Dec 2019 11:41:57 +0000 (12:41 +0100)
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>
src/qemu/qemu_blockjob.c
src/qemu/qemu_blockjob.h
src/qemu/qemu_domain.c

index ce4056a7b3139c8a2f5a195d009996dbb8509ee4..b17577e9879744f1544ee99aa9b8cac94179946c 100644 (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
index 4734984c9966bd62ea9dc2c6ba037bab0560caff..52b03aaf9e8e0d680b91210451993ed6d6615d04 100644 (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);
index 1be6cfccfff89ffc5e052c031cee262465fe51bf..873a397ac6e00e29962518aedcfe4970b3f1c701 100644 (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: