[libvirt PATCH v2 08/10] qemu: block: add function to wait for blockcommits and collect results

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is the third phase of snapshot deletion.  Blockcommits to delete the
snapshot have been launched and now we can wait for them to finish, check
results and report errors if any.

Signed-off-by: Pavel Mores <pmores@xxxxxxxxxx>
---
 src/qemu/qemu_driver.c | 59 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 35b7fb69d5..a2629e9002 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16941,6 +16941,65 @@ qemuDomainSnapshotDeleteExternalLaunchJobs(virDomainObjPtr vm,
 }
 
 
+static int
+qemuDomainSnapshotDeleteExternalWaitForJobs(virDomainObjPtr vm,
+                                            virQEMUDriverPtr driver,
+                                            const virBlockCommitDesc *blockCommitDescs,
+                                            int numDescs)
+{
+    size_t i;
+
+    for (i = 0; i < numDescs; i++) {
+        virDomainDiskDefPtr disk = blockCommitDescs[i].disk;
+        bool isActive = blockCommitDescs[i].isActive;
+
+        /* wait for the blockcommit job to finish (in particular, reach
+         * one of the finished QEMU_BLOCKJOB_STATE_* states)... */
+        g_autoptr(qemuBlockJobData) job = NULL;
+
+        if (!(job = qemuBlockJobDiskGetJob(disk))) {
+            virReportError(VIR_ERR_OPERATION_INVALID,
+                        _("disk %s does not have an active block job"), disk->dst);
+            return -1;
+        }
+
+        qemuBlockJobSyncBegin(job);
+        qemuBlockJobUpdate(vm, job, QEMU_ASYNC_JOB_NONE);
+        while (job->state != QEMU_BLOCKJOB_STATE_READY &&
+               job->state != QEMU_BLOCKJOB_STATE_FAILED &&
+               job->state != QEMU_BLOCKJOB_STATE_CANCELLED &&
+               job->state != QEMU_BLOCKJOB_STATE_COMPLETED) {
+
+            if (virDomainObjWait(vm) < 0)
+                return -1;
+            qemuBlockJobUpdate(vm, job, QEMU_ASYNC_JOB_NONE);
+        }
+        qemuBlockJobSyncEnd(vm, job, QEMU_ASYNC_JOB_NONE);
+
+        if ((isActive && job->state != QEMU_BLOCKJOB_STATE_READY) ||
+            (!isActive && job->state != QEMU_BLOCKJOB_STATE_COMPLETED)) {
+            virReportError(VIR_ERR_OPERATION_INVALID,
+                        _("blockcomit job failed for disk %s"), disk->dst);
+            /* TODO Apr 30, 2020: how to handle this?  Bailing out doesn't
+             * seem an obvious option in this case as all blockjobs are now
+             * created and running - if any of them are to fail they will,
+             * regardless of whether we break here.  It might make more
+             * sense to continue and at least report all errors. */
+            /*return -1;*/
+        }
+
+        /* ... and pivot if necessary */
+        if (isActive) {
+            if (qemuDomainBlockJobAbortImpl(driver, vm, disk->dst,
+                                            VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT) < 0)
+                return -1;
+        }
+    }
+
+    return 0;
+}
+
+
 static int
 qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
                          unsigned int flags)
-- 
2.24.1





[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux