[libvirt] [PATCH RFC 40/40] qemu: blockjob: Implement concluded blockjob handler for backup blockjobs

Peter Krempa pkrempa at redhat.com
Fri Oct 18 16:11:25 UTC 2019


After the individual sub-blockjobs of a backup libvirt job finish we
must detect it and notify the parent job, so that it can be properly
terminated.

Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 src/qemu/qemu_blockjob.c     | 45 ++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_monitor_json.c |  4 ++++
 2 files changed, 49 insertions(+)

diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
index 6f190b3485..acfc07638b 100644
--- a/src/qemu/qemu_blockjob.c
+++ b/src/qemu/qemu_blockjob.c
@@ -27,6 +27,7 @@
 #include "qemu_block.h"
 #include "qemu_domain.h"
 #include "qemu_alias.h"
+#include "qemu_backup.h"

 #include "conf/domain_conf.h"
 #include "conf/domain_event.h"
@@ -1282,6 +1283,49 @@ qemuBlockJobProcessEventConcludedCreate(virQEMUDriverPtr driver,
 }


+static void
+qemuBlockJobProcessEventConcludedBackup(virQEMUDriverPtr driver,
+                                        virDomainObjPtr vm,
+                                        qemuBlockJobDataPtr job,
+                                        qemuDomainAsyncJob asyncJob,
+                                        qemuBlockjobState newstate)
+{
+    g_autoptr(qemuBlockStorageSourceAttachData) backend = NULL;
+    g_autoptr(virJSONValue) actions = NULL;
+
+    qemuBackupNotifyBlockjobEnd(vm, job->data.backup.jobid, job->disk, newstate);
+
+    if (job->data.backup.store &&
+        !(backend = qemuBlockStorageSourceDetachPrepare(job->data.backup.store, NULL)))
+        return;
+
+    if (job->data.backup.bitmap) {
+        if (!(actions = virJSONValueNewArray()))
+            return;
+
+        if (qemuMonitorTransactionBitmapRemove(actions,
+                                               job->disk->src->nodeformat,
+                                               job->data.backup.bitmap) < 0)
+            return;
+    }
+
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+        return;
+
+    if (backend)
+        qemuBlockStorageSourceAttachRollback(qemuDomainGetMonitor(vm), backend);
+
+    if (actions)
+        qemuMonitorTransaction(qemuDomainGetMonitor(vm), &actions);
+
+    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        return;
+
+    if (job->data.backup.store)
+        qemuDomainStorageSourceAccessRevoke(driver, vm, job->data.backup.store);
+}
+
+
 static void
 qemuBlockJobEventProcessConcludedTransition(qemuBlockJobDataPtr job,
                                             virQEMUDriverPtr driver,
@@ -1320,6 +1364,7 @@ qemuBlockJobEventProcessConcludedTransition(qemuBlockJobDataPtr job,
         break;

     case QEMU_BLOCKJOB_TYPE_BACKUP:
+        qemuBlockJobProcessEventConcludedBackup(driver, vm, job, asyncJob, job->newstate);
     case QEMU_BLOCKJOB_TYPE_NONE:
     case QEMU_BLOCKJOB_TYPE_INTERNAL:
     case QEMU_BLOCKJOB_TYPE_LAST:
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 51603d2631..e4f1db284d 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -1152,6 +1152,8 @@ qemuMonitorJSONHandleBlockJobImpl(qemuMonitorPtr mon,
         type = VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT;
     else if (STREQ(type_str, "mirror"))
         type = VIR_DOMAIN_BLOCK_JOB_TYPE_COPY;
+    else if (STREQ(type_str, "backup"))
+        type = VIR_DOMAIN_BLOCK_JOB_TYPE_BACKUP;

     switch ((virConnectDomainEventBlockJobStatus) event) {
     case VIR_DOMAIN_BLOCK_JOB_COMPLETED:
@@ -4858,6 +4860,8 @@ qemuMonitorJSONParseBlockJobInfo(virHashTablePtr blockJobs,
         info->type = VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT;
     else if (STREQ(type, "mirror"))
         info->type = VIR_DOMAIN_BLOCK_JOB_TYPE_COPY;
+    else if (STREQ(type, "backup"))
+        info->type = VIR_DOMAIN_BLOCK_JOB_TYPE_BACKUP;
     else
         info->type = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;

-- 
2.21.0




More information about the libvir-list mailing list