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 ueful
also for the new handlers. Split it out which also simplifies it.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_blockjob.c | 64 ++++++++++++++++++++++++----------------
1 file changed, 39 insertions(+), 25 deletions(-)
diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
index a3109d3934..f9e79db131 100644
--- a/src/qemu/qemu_blockjob.c
+++ b/src/qemu/qemu_blockjob.c
@@ -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 it's 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
--
2.21.0