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(a)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