[libvirt] [PATCH v3 05/24] qemu: Cancel storage migration in parallel

2015-06-10 Thread Jiri Denemark
Instead of cancelling disk mirrors sequentially, let's just call
block-job-cancel for all migrating disks and then wait until all
disappear.

In case we cancel disk mirrors at the end of successful migration we
also need to check all block jobs completed successfully. Otherwise we
have to abort the migration.

Signed-off-by: Jiri Denemark jdene...@redhat.com
---

Notes:
Version 3:
- new patch (separated from qemu: Use domain condition for
  synchronous block jobs)
- get rid of bool *failed parameter in qemuMigrationDriveMirrorCancelled

 src/qemu/qemu_migration.c | 196 +++---
 1 file changed, 134 insertions(+), 62 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 83d6c22..11504eb 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1769,76 +1769,122 @@ qemuMigrationDriveMirrorReady(virQEMUDriverPtr driver,
 }
 
 
-/**
- * qemuMigrationCancelOneDriveMirror:
- * @driver: qemu driver
- * @vm: domain
+/*
+ * If @check is true, the function will report an error and return a different
+ * code in case a block job fails. This way we can properly abort migration in
+ * case some block jobs failed once all memory has already been transferred.
  *
- * Cancel all drive-mirrors started by qemuMigrationDriveMirror.
- * Any pending block job events for the mirrored disks will be
- * processed.
- *
- * Returns 0 on success, -1 otherwise.
+ * Returns 1 if all mirrors are gone,
+ * 0 if some mirrors are still active,
+ * -1 some mirrors failed but some are still active,
+ * -2 all mirrors are gone but some of them failed.
  */
 static int
-qemuMigrationCancelOneDriveMirror(virQEMUDriverPtr driver,
+qemuMigrationDriveMirrorCancelled(virQEMUDriverPtr driver,
   virDomainObjPtr vm,
-  virDomainDiskDefPtr disk)
+  bool check)
 {
-qemuDomainObjPrivatePtr priv = vm-privateData;
-char *diskAlias = NULL;
-int ret = -1;
+size_t i;
+size_t active = 0;
+int status;
+bool failed = false;
 
-/* No need to cancel if mirror already aborted */
-if (disk-mirrorState == VIR_DOMAIN_DISK_MIRROR_STATE_ABORT) {
-ret = 0;
-} else {
-virConnectDomainEventBlockJobStatus status = -1;
+for (i = 0; i  vm-def-ndisks; i++) {
+virDomainDiskDefPtr disk = vm-def-disks[i];
+qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
 
-if (virAsprintf(diskAlias, %s%s,
-QEMU_DRIVE_HOST_PREFIX, disk-info.alias)  0)
-goto cleanup;
+if (!diskPriv-migrating)
+continue;
 
-if (qemuDomainObjEnterMonitorAsync(driver, vm,
-   QEMU_ASYNC_JOB_MIGRATION_OUT)  0)
-goto endjob;
-ret = qemuMonitorBlockJobCancel(priv-mon, diskAlias, true);
-if (qemuDomainObjExitMonitor(driver, vm)  0)
-goto endjob;
-
-if (ret  0) {
-virDomainBlockJobInfo info;
-
-/* block-job-cancel can fail if QEMU simultaneously
- * aborted the job; probe for it again to detect this */
-if (qemuMonitorBlockJobInfo(priv-mon, diskAlias,
-info, NULL) == 0) {
-ret = 0;
-} else {
+status = qemuBlockJobUpdate(driver, vm, disk);
+switch (status) {
+case VIR_DOMAIN_BLOCK_JOB_FAILED:
+if (check) {
 virReportError(VIR_ERR_OPERATION_FAILED,
-   _(could not cancel migration of disk %s),
+   _(migration of disk %s failed),
disk-dst);
+failed = true;
 }
+/* fallthrough */
+case VIR_DOMAIN_BLOCK_JOB_CANCELED:
+case VIR_DOMAIN_BLOCK_JOB_COMPLETED:
+qemuBlockJobSyncEnd(driver, vm, disk);
+diskPriv-migrating = false;
+break;
 
-goto endjob;
+default:
+active++;
 }
+}
 
-/* Mirror may become ready before cancellation takes
- * effect; loop if we get that event first */
-while (1) {
-status = qemuBlockJobUpdate(driver, vm, disk);
-if (status != -1  status != VIR_DOMAIN_BLOCK_JOB_READY)
-break;
-if ((ret = virDomainObjWait(vm))  0)
-goto endjob;
+if (failed) {
+if (active) {
+VIR_DEBUG(Some disk mirrors failed; still waiting for %zu 
+  disk mirrors to finish, active);
+return -1;
+} else {
+VIR_DEBUG(All disk mirrors are gone; some of them failed);
+return -2;
+}
+} else {
+if (active) {
+VIR_DEBUG(Waiting for %zu disk mirrors to finish, active);
+

Re: [libvirt] [PATCH v3 05/24] qemu: Cancel storage migration in parallel

2015-06-10 Thread Peter Krempa
On Wed, Jun 10, 2015 at 15:42:39 +0200, Jiri Denemark wrote:
 Instead of cancelling disk mirrors sequentially, let's just call
 block-job-cancel for all migrating disks and then wait until all
 disappear.
 
 In case we cancel disk mirrors at the end of successful migration we
 also need to check all block jobs completed successfully. Otherwise we
 have to abort the migration.
 
 Signed-off-by: Jiri Denemark jdene...@redhat.com
 ---
 

ACK,

Peter


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