[libvirt PATCH v2 28/31] qemu_process: abort snapshot delete when daemon starts

Pavel Hrdina phrdina at redhat.com
Thu Jan 5 11:47:04 UTC 2023


If the daemon crashes or is restarted while the snapshot delete is in
progress we have to handle it gracefully to not leave any block jobs
active.

For now we will simply abort the snapshot delete operation so user can
start it again. We need to refuse deleting external snapshots if there
is already another active job as we would have to figure out which jobs
we can abort.

Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
Reviewed-by: Peter Krempa <pkrempa at redhat.com>
---
 src/qemu/qemu_process.c  | 32 ++++++++++++++++++++++++++++++++
 src/qemu/qemu_snapshot.c |  7 +++++++
 2 files changed, 39 insertions(+)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index b6adcf2f2a..09ab231aaa 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3677,6 +3677,37 @@ qemuProcessRecoverMigration(virQEMUDriver *driver,
 }
 
 
+static void
+qemuProcessAbortSnapshotDelete(virDomainObj *vm)
+{
+    size_t i;
+    qemuDomainObjPrivate *priv = vm->privateData;
+
+    for (i = 0; i < vm->def->ndisks; i++) {
+        virDomainDiskDef *disk = vm->def->disks[i];
+        g_autoptr(qemuBlockJobData) diskJob = qemuBlockJobDiskGetJob(disk);
+
+        if (!diskJob)
+            continue;
+
+        if (diskJob->type != QEMU_BLOCKJOB_TYPE_COMMIT &&
+            diskJob->type != QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT) {
+            continue;
+        }
+
+        qemuBlockJobSyncBegin(diskJob);
+
+        qemuDomainObjEnterMonitor(vm);
+        ignore_value(qemuMonitorBlockJobCancel(priv->mon, diskJob->name, false));
+        qemuDomainObjExitMonitor(vm);
+
+        diskJob->state = QEMU_BLOCKJOB_STATE_ABORTING;
+
+        qemuBlockJobSyncEnd(vm, diskJob, VIR_ASYNC_JOB_NONE);
+    }
+}
+
+
 static int
 qemuProcessRecoverJob(virQEMUDriver *driver,
                       virDomainObj *vm,
@@ -3726,6 +3757,7 @@ qemuProcessRecoverJob(virQEMUDriver *driver,
                           vm->def->name);
             }
         }
+        qemuProcessAbortSnapshotDelete(vm);
         break;
 
     case VIR_ASYNC_JOB_START:
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index 0ed8a82aa9..f5b88daa5d 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -3095,6 +3095,13 @@ qemuSnapshotDeleteValidate(virDomainObj *vm,
         }
     }
 
+    if (virDomainSnapshotIsExternal(snap) &&
+        qemuDomainHasBlockjob(vm, false)) {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                       _("cannot delete external snapshots when there is another active block job"));
+        return -1;
+    }
+
     if (virDomainSnapshotIsExternal(snap) &&
         !(flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-- 
2.39.0



More information about the libvir-list mailing list