[libvirt] [PATCH v3 2/2] qemu: report drive mirror errors on migration

Nikolay Shirokovskiy nshirokovskiy at virtuozzo.com
Wed Nov 2 09:16:00 UTC 2016


---
 src/qemu/qemu_blockjob.c  | 14 +++++++++---
 src/qemu/qemu_blockjob.h  |  3 ++-
 src/qemu/qemu_driver.c    |  4 ++--
 src/qemu/qemu_migration.c | 54 +++++++++++++++++++++++++++++++++--------------
 4 files changed, 53 insertions(+), 22 deletions(-)

diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
index 0796d4f..bcc76e7 100644
--- a/src/qemu/qemu_blockjob.c
+++ b/src/qemu/qemu_blockjob.c
@@ -45,6 +45,7 @@ VIR_LOG_INIT("qemu.qemu_blockjob");
  * @driver: qemu driver
  * @vm: domain
  * @disk: domain disk
+ * @error: error (output parameter)
  *
  * Update disk's mirror state in response to a block job event stored in
  * blockJobStatus by qemuProcessHandleBlockJob event handler.
@@ -54,17 +55,24 @@ VIR_LOG_INIT("qemu.qemu_blockjob");
 int
 qemuBlockJobUpdate(virQEMUDriverPtr driver,
                    virDomainObjPtr vm,
-                   virDomainDiskDefPtr disk)
+                   virDomainDiskDefPtr disk,
+                   char **error)
 {
     qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
     int status = diskPriv->blockJobStatus;
 
+    if (error)
+        *error = NULL;
+
     if (status != -1) {
         qemuBlockJobEventProcess(driver, vm, disk,
                                  diskPriv->blockJobType,
                                  diskPriv->blockJobStatus);
         diskPriv->blockJobStatus = -1;
-        VIR_FREE(diskPriv->blockJobError);
+        if (error)
+            VIR_STEAL_PTR(*error, diskPriv->blockJobError);
+        else
+            VIR_FREE(diskPriv->blockJobError);
     }
 
     return status;
@@ -243,6 +251,6 @@ qemuBlockJobSyncEnd(virQEMUDriverPtr driver,
                     virDomainDiskDefPtr disk)
 {
     VIR_DEBUG("disk=%s", disk->dst);
-    qemuBlockJobUpdate(driver, vm, disk);
+    qemuBlockJobUpdate(driver, vm, disk, NULL);
     QEMU_DOMAIN_DISK_PRIVATE(disk)->blockJobSync = false;
 }
diff --git a/src/qemu/qemu_blockjob.h b/src/qemu/qemu_blockjob.h
index 775ce95..c452edc 100644
--- a/src/qemu/qemu_blockjob.h
+++ b/src/qemu/qemu_blockjob.h
@@ -27,7 +27,8 @@
 
 int qemuBlockJobUpdate(virQEMUDriverPtr driver,
                        virDomainObjPtr vm,
-                       virDomainDiskDefPtr disk);
+                       virDomainDiskDefPtr disk,
+                       char **error);
 void qemuBlockJobEventProcess(virQEMUDriverPtr driver,
                               virDomainObjPtr vm,
                               virDomainDiskDefPtr disk,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b8cec49..c9a3467 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16346,13 +16346,13 @@ qemuDomainBlockJobAbort(virDomainPtr dom,
                                      VIR_DOMAIN_BLOCK_JOB_CANCELED);
         } else {
             qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
-            qemuBlockJobUpdate(driver, vm, disk);
+            qemuBlockJobUpdate(driver, vm, disk, NULL);
             while (diskPriv->blockjob) {
                 if (virDomainObjWait(vm) < 0) {
                     ret = -1;
                     goto endjob;
                 }
-                qemuBlockJobUpdate(driver, vm, disk);
+                qemuBlockJobUpdate(driver, vm, disk, NULL);
             }
         }
     }
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 1c4a80c..a9bc3db 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1859,17 +1859,25 @@ qemuMigrationDriveMirrorReady(virQEMUDriverPtr driver,
     for (i = 0; i < vm->def->ndisks; i++) {
         virDomainDiskDefPtr disk = vm->def->disks[i];
         qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
+        char *error = NULL;
 
         if (!diskPriv->migrating)
             continue;
 
-        status = qemuBlockJobUpdate(driver, vm, disk);
+        status = qemuBlockJobUpdate(driver, vm, disk, &error);
         if (status == VIR_DOMAIN_BLOCK_JOB_FAILED) {
-            virReportError(VIR_ERR_OPERATION_FAILED,
-                           _("migration of disk %s failed"),
-                           disk->dst);
+            if (error) {
+                virReportError(VIR_ERR_OPERATION_FAILED,
+                               _("migration of disk %s failed: %s"),
+                               disk->dst, error);
+                VIR_FREE(error);
+            } else {
+                virReportError(VIR_ERR_OPERATION_FAILED,
+                               _("migration of disk %s failed"), disk->dst);
+            }
             return -1;
         }
+        VIR_FREE(error);
 
         if (disk->mirrorState != VIR_DOMAIN_DISK_MIRROR_STATE_READY)
             notReady++;
@@ -1908,17 +1916,23 @@ qemuMigrationDriveMirrorCancelled(virQEMUDriverPtr driver,
     for (i = 0; i < vm->def->ndisks; i++) {
         virDomainDiskDefPtr disk = vm->def->disks[i];
         qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
+        char *error = NULL;
 
         if (!diskPriv->migrating)
             continue;
 
-        status = qemuBlockJobUpdate(driver, vm, disk);
+        status = qemuBlockJobUpdate(driver, vm, disk, &error);
         switch (status) {
         case VIR_DOMAIN_BLOCK_JOB_FAILED:
             if (check) {
-                virReportError(VIR_ERR_OPERATION_FAILED,
-                               _("migration of disk %s failed"),
-                               disk->dst);
+                if (error) {
+                    virReportError(VIR_ERR_OPERATION_FAILED,
+                                   _("migration of disk %s failed: %s"),
+                                   disk->dst, error);
+                } else {
+                    virReportError(VIR_ERR_OPERATION_FAILED,
+                                   _("migration of disk %s failed"), disk->dst);
+                }
                 failed = true;
             }
             /* fallthrough */
@@ -1931,6 +1945,7 @@ qemuMigrationDriveMirrorCancelled(virQEMUDriverPtr driver,
         default:
             active++;
         }
+        VIR_FREE(error);
     }
 
     if (failed) {
@@ -1968,24 +1983,30 @@ qemuMigrationCancelOneDriveMirror(virQEMUDriverPtr driver,
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     char *diskAlias = NULL;
+    char *error = NULL;
     int ret = -1;
     int status;
     int rv;
 
-    status = qemuBlockJobUpdate(driver, vm, disk);
+    status = qemuBlockJobUpdate(driver, vm, disk, &error);
     switch (status) {
     case VIR_DOMAIN_BLOCK_JOB_FAILED:
     case VIR_DOMAIN_BLOCK_JOB_CANCELED:
         if (failNoJob) {
-            virReportError(VIR_ERR_OPERATION_FAILED,
-                           _("migration of disk %s failed"),
-                           disk->dst);
-            return -1;
+            if (error) {
+                virReportError(VIR_ERR_OPERATION_FAILED,
+                               _("migration of disk %s failed: %s"),
+                               disk->dst, error);
+            } else {
+                virReportError(VIR_ERR_OPERATION_FAILED,
+                               _("migration of disk %s failed"), disk->dst);
+            }
+            goto cleanup;
         }
-        return 1;
-
+    /* fallthrough */
     case VIR_DOMAIN_BLOCK_JOB_COMPLETED:
-        return 1;
+        ret = 1;
+        goto cleanup;
     }
 
     if (!(diskAlias = qemuAliasFromDisk(disk)))
@@ -2003,6 +2024,7 @@ qemuMigrationCancelOneDriveMirror(virQEMUDriverPtr driver,
 
  cleanup:
     VIR_FREE(diskAlias);
+    VIR_FREE(error);
     return ret;
 }
 
-- 
1.8.3.1




More information about the libvir-list mailing list