Re: [libvirt] [PATCH 11/12] qemu: Add blockdev support for the block copy job

2019-08-15 Thread Ján Tomko

On Thu, Aug 08, 2019 at 06:00:41PM +0200, Peter Krempa wrote:

Implement job handling for the block copy job (drive/blockdev-mirror)
when using -blockdev. In contrast to the previously implemented
blockjobs the block copy job introduces new images to the running qemu
instance, thus requires a bit more handling.

When copying to new images the code now makes use of blockdev-create to
format the images explicitly rather than depending on automagic qemu
behaviour.

Signed-off-by: Peter Krempa 
---
src/qemu/qemu_blockjob.c  | 87 +
src/qemu/qemu_blockjob.h  | 16 +++
src/qemu/qemu_domain.c| 13 +++
src/qemu/qemu_driver.c| 97 ---
.../blockjob-blockdev-in.xml  | 14 +++
5 files changed, 216 insertions(+), 11 deletions(-)



Reviewed-by: Ján Tomko 

Jano


signature.asc
Description: PGP signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH 11/12] qemu: Add blockdev support for the block copy job

2019-08-08 Thread Peter Krempa
Implement job handling for the block copy job (drive/blockdev-mirror)
when using -blockdev. In contrast to the previously implemented
blockjobs the block copy job introduces new images to the running qemu
instance, thus requires a bit more handling.

When copying to new images the code now makes use of blockdev-create to
format the images explicitly rather than depending on automagic qemu
behaviour.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_blockjob.c  | 87 +
 src/qemu/qemu_blockjob.h  | 16 +++
 src/qemu/qemu_domain.c| 13 +++
 src/qemu/qemu_driver.c| 97 ---
 .../blockjob-blockdev-in.xml  | 14 +++
 5 files changed, 216 insertions(+), 11 deletions(-)

diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
index 70550d17e7..3003e9c518 100644
--- a/src/qemu/qemu_blockjob.c
+++ b/src/qemu/qemu_blockjob.c
@@ -309,6 +309,40 @@ qemuBlockJobNewCreate(virDomainObjPtr vm,
 }


+qemuBlockJobDataPtr
+qemuBlockJobDiskNewCopy(virDomainObjPtr vm,
+virDomainDiskDefPtr disk,
+virStorageSourcePtr mirror,
+bool shallow,
+bool reuse)
+{
+qemuDomainObjPrivatePtr priv = vm->privateData;
+VIR_AUTOUNREF(qemuBlockJobDataPtr) job = NULL;
+VIR_AUTOFREE(char *) jobname = NULL;
+
+if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV)) {
+if (virAsprintf(, "copy-%s-%s", disk->dst, 
disk->src->nodeformat) < 0)
+return NULL;
+} else {
+if (!(jobname = qemuAliasDiskDriveFromDisk(disk)))
+return NULL;
+}
+
+if (!(job = qemuBlockJobDataNew(QEMU_BLOCKJOB_TYPE_COPY, jobname)))
+return NULL;
+
+job->mirrorChain = virObjectRef(mirror);
+
+if (shallow && !reuse)
+job->data.copy.shallownew = true;
+
+if (qemuBlockJobRegister(job, vm, disk, true) < 0)
+return NULL;
+
+VIR_RETURN_PTR(job);
+}
+
+
 /**
  * qemuBlockJobDiskGetJob:
  * @disk: disk definition
@@ -1043,6 +1077,50 @@ 
qemuBlockJobProcessEventCompletedActiveCommit(virQEMUDriverPtr driver,
 }


+static void
+qemuBlockJobProcessEventConcludedCopyPivot(virQEMUDriverPtr driver,
+   virDomainObjPtr vm,
+   qemuBlockJobDataPtr job,
+   qemuDomainAsyncJob asyncJob)
+{
+VIR_DEBUG("copy job '%s' on VM '%s' pivoted", job->name, vm->def->name);
+
+if (!job->disk)
+return;
+
+/* for shallow copy without reusing external image the user can either not
+ * specify the backing chain in which case libvirt will open and use the
+ * chain the user provided or not specify a chain in which case we'll
+ * inherit the rest of the chain */
+if (job->data.copy.shallownew &&
+!virStorageSourceIsBacking(job->disk->mirror->backingStore))
+VIR_STEAL_PTR(job->disk->mirror->backingStore, 
job->disk->src->backingStore);
+
+qemuBlockJobRewriteConfigDiskSource(vm, job->disk, job->disk->mirror);
+
+qemuBlockJobEventProcessConcludedRemoveChain(driver, vm, asyncJob, 
job->disk->src);
+virObjectUnref(job->disk->src);
+VIR_STEAL_PTR(job->disk->src, job->disk->mirror);
+}
+
+
+static void
+qemuBlockJobProcessEventConcludedCopyAbort(virQEMUDriverPtr driver,
+   virDomainObjPtr vm,
+   qemuBlockJobDataPtr job,
+   qemuDomainAsyncJob asyncJob)
+{
+VIR_DEBUG("copy job '%s' on VM '%s' aborted", job->name, vm->def->name);
+
+if (!job->disk)
+return;
+
+qemuBlockJobEventProcessConcludedRemoveChain(driver, vm, asyncJob, 
job->disk->mirror);
+virObjectUnref(job->disk->mirror);
+job->disk->mirror = NULL;
+}
+
+
 static void
 qemuBlockJobProcessEventConcludedCreate(virQEMUDriverPtr driver,
 virDomainObjPtr vm,
@@ -,6 +1189,12 @@ 
qemuBlockJobEventProcessConcludedTransition(qemuBlockJobDataPtr job,
 break;

 case QEMU_BLOCKJOB_TYPE_COPY:
+if (job->state == QEMU_BLOCKJOB_STATE_PIVOTING)
+qemuBlockJobProcessEventConcludedCopyPivot(driver, vm, job, 
asyncJob);
+else
+qemuBlockJobProcessEventConcludedCopyAbort(driver, vm, job, 
asyncJob);
+break;
+
 case QEMU_BLOCKJOB_TYPE_NONE:
 case QEMU_BLOCKJOB_TYPE_INTERNAL:
 case QEMU_BLOCKJOB_TYPE_LAST:
@@ -1138,6 +1222,9 @@ 
qemuBlockJobEventProcessConcludedTransition(qemuBlockJobDataPtr job,
 break;

 case QEMU_BLOCKJOB_TYPE_COPY:
+qemuBlockJobProcessEventConcludedCopyAbort(driver, vm, job, 
asyncJob);
+break;
+
 case QEMU_BLOCKJOB_TYPE_NONE:
 case QEMU_BLOCKJOB_TYPE_INTERNAL:
 case