23265d
From 48fc7e172ed82fbe8b377c11cff2c9d47fbb37c8 Mon Sep 17 00:00:00 2001
23265d
Message-Id: <48fc7e172ed82fbe8b377c11cff2c9d47fbb37c8@dist-git>
23265d
From: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
23265d
Date: Fri, 7 Apr 2017 14:06:25 +0300
23265d
Subject: [PATCH] qemu: migration: fix race on cancelling drive mirror
23265d
23265d
0feebab2 adds calling qemuBlockNodeNamesDetect for completed job
23265d
on updating block jobs. This affects cancelling drive mirror logic as
23265d
this function drops vm lock. Now we have to recheck all disks
23265d
before the disk with the completed block job before going
23265d
to wait for block job events.
23265d
23265d
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
23265d
(cherry picked from commit bc82d1eaf66bfdfde80a64e7feedb60c6d1d2505)
23265d
23265d
https://bugzilla.redhat.com/show_bug.cgi?id=1530129
23265d
23265d
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
23265d
---
23265d
 src/qemu/qemu_migration.c | 15 +++++++++++++++
23265d
 1 file changed, 15 insertions(+)
23265d
23265d
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
23265d
index d2b691bd2b..60722cbf6c 100644
23265d
--- a/src/qemu/qemu_migration.c
23265d
+++ b/src/qemu/qemu_migration.c
23265d
@@ -654,9 +654,11 @@ qemuMigrationDriveMirrorCancelled(virQEMUDriverPtr driver,
23265d
 {
23265d
     size_t i;
23265d
     size_t active = 0;
23265d
+    size_t completed = 0;
23265d
     int status;
23265d
     bool failed = false;
23265d
 
23265d
+ retry:
23265d
     for (i = 0; i < vm->def->ndisks; i++) {
23265d
         virDomainDiskDefPtr disk = vm->def->disks[i];
23265d
         qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
23265d
@@ -683,6 +685,19 @@ qemuMigrationDriveMirrorCancelled(virQEMUDriverPtr driver,
23265d
         default:
23265d
             active++;
23265d
         }
23265d
+
23265d
+        if (status == VIR_DOMAIN_BLOCK_JOB_COMPLETED)
23265d
+            completed++;
23265d
+    }
23265d
+
23265d
+    /* Updating completed block job drops the lock thus we have to recheck
23265d
+     * block jobs for disks that reside before the disk(s) with completed
23265d
+     * block job.
23265d
+     */
23265d
+    if (completed > 0) {
23265d
+        completed = 0;
23265d
+        active = 0;
23265d
+        goto retry;
23265d
     }
23265d
 
23265d
     if (failed) {
23265d
-- 
23265d
2.15.1
23265d