]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: blockjob: Split out update of persistent XML disk's source on mirror jobs
authorPeter Krempa <pkrempa@redhat.com>
Wed, 24 Jul 2019 15:17:17 +0000 (17:17 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Thu, 25 Jul 2019 11:21:33 +0000 (13:21 +0200)
Both active block commit and block copy modify the disk source of the
active definition and thus also must modify the corresponding inactive
definition source so that the VM starts up later. This is currently
implemented in the legacy block job handler but the logic will be useful
also for the new handlers. Split it out which also simplifies it.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
ACKed-by: Eric Blake <eblake@redhat.com>
src/qemu/qemu_blockjob.c

index 52065f07caa953873a22925041cce40ebf8d25d9..d0805dbcc5b315f8650bba81c051fad291453f1f 100644 (file)
@@ -434,6 +434,44 @@ qemuBlockJobEmitEvents(virQEMUDriverPtr driver,
 }
 
 
+/**
+ * qemuBlockJobRewriteConfigDiskSource:
+ * @vm: domain object
+ * @disk: live definition disk
+ * @newsrc: new source which should be also considered for the new disk
+ *
+ * For block jobs which modify the running disk source it is required that we
+ * try our best to update the config XML's disk source as well in most cases.
+ *
+ * This helper finds the disk from the persistent definition corresponding to
+ * @disk and updates its source to @newsrc.
+ */
+static void
+qemuBlockJobRewriteConfigDiskSource(virDomainObjPtr vm,
+                                    virDomainDiskDefPtr disk,
+                                    virStorageSourcePtr newsrc)
+{
+    virDomainDiskDefPtr persistDisk = NULL;
+    VIR_AUTOUNREF(virStorageSourcePtr) copy = NULL;
+
+    if (!vm->newDef)
+        return;
+
+    if (!(persistDisk = virDomainDiskByName(vm->newDef, disk->dst, false)))
+        return;
+
+    if (!(copy = virStorageSourceCopy(newsrc, false)) ||
+        virStorageSourceInitChainElement(copy, persistDisk->src, true) < 0) {
+        VIR_WARN("Unable to update persistent definition on vm %s after block job",
+                 vm->def->name);
+        return;
+    }
+
+    virObjectUnref(persistDisk->src);
+    VIR_STEAL_PTR(persistDisk->src, copy);
+}
+
+
 static void
 qemuBlockJobEventProcessLegacyCompleted(virQEMUDriverPtr driver,
                                         virDomainObjPtr vm,
@@ -441,36 +479,12 @@ qemuBlockJobEventProcessLegacyCompleted(virQEMUDriverPtr driver,
                                         int asyncJob)
 {
     virDomainDiskDefPtr disk = job->disk;
-    virDomainDiskDefPtr persistDisk = NULL;
 
     if (!disk)
         return;
 
     if (disk->mirrorState == VIR_DOMAIN_DISK_MIRROR_STATE_PIVOT) {
-        if (vm->newDef) {
-            virStorageSourcePtr copy = NULL;
-
-            if ((persistDisk = virDomainDiskByName(vm->newDef,
-                                                   disk->dst, false))) {
-                copy = virStorageSourceCopy(disk->mirror, false);
-                if (!copy ||
-                    virStorageSourceInitChainElement(copy,
-                                                     persistDisk->src,
-                                                     true) < 0) {
-                    VIR_WARN("Unable to update persistent definition "
-                             "on vm %s after block job",
-                             vm->def->name);
-                    virObjectUnref(copy);
-                    copy = NULL;
-                    persistDisk = NULL;
-                }
-            }
-            if (copy) {
-                virObjectUnref(persistDisk->src);
-                persistDisk->src = copy;
-            }
-        }
-
+        qemuBlockJobRewriteConfigDiskSource(vm, disk, disk->mirror);
         /* XXX We want to revoke security labels as well as audit that
          * revocation, before dropping the original source.  But it gets
          * tricky if both source and mirror share common backing files (we