[libvirt] [PATCH v2 12/12] qemu: show disks stats for nbd migration

Nikolay Shirokovskiy nshirokovskiy at virtuozzo.com
Wed Dec 28 14:39:21 UTC 2016


There is no disks stats when migrating with VIR_MIGRATE_NON_SHARED_*
for qemu that supports nbd. The reason is that disks are copied via disk mirroring
and not in the scope of migration job itself. Below
a couble of issues of the implementation are described.

'total' field is set from 'end' field of block job info for the
sake of simplicity. This is true only when there is no guest disk
activity during migration. If there is an activity then 'end' will
grow while 'total' is an estimation that should stay constant.
I guess this can be fixed by setting 'total' to disk 'capacity'.

There is also known possible corner case issue with this implementation.
There is a chance that client asking for stats at the process of the
mirroring stopping on successfull migration will see only part of mirroring disks
and thus will receive inconsisent partial info.
---
 docs/news.html.in         |  4 ++++
 src/qemu/qemu_driver.c    |  3 ++-
 src/qemu/qemu_migration.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_migration.h |  5 +++++
 4 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/docs/news.html.in b/docs/news.html.in
index 22611db..8036cf8 100644
--- a/docs/news.html.in
+++ b/docs/news.html.in
@@ -42,6 +42,10 @@
           cpu cycles, stalled backend cpu cycles, and ref cpu
           cycles by applications running on the platform
           </li>
+          <li>qemu: show disks stats for nbd disks migration<br/>
+          Show disks stats in migrations stats in disks copy phase
+          of migration with non-shared disks.
+          </li>
         </ul>
       </li>
       <li><strong>Bug fixes</strong>
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0d2f9de..1881466 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13037,7 +13037,8 @@ qemuDomainGetMigrationJobStats(virQEMUDriverPtr driver,
     if (qemuDomainJobInfoUpdateTime(jobInfo) < 0)
         return -1;
 
-    return 0;
+    return qemuMigrationFetchMirrorStats(driver, vm, QEMU_ASYNC_JOB_NONE,
+                                         &jobInfo->stats);
 }
 
 
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index b26b8ad..006c264 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2582,6 +2582,59 @@ qemuMigrationUpdateJobType(qemuDomainJobInfoPtr jobInfo)
     }
 }
 
+int
+qemuMigrationFetchMirrorStats(virQEMUDriverPtr driver,
+                              virDomainObjPtr vm,
+                              qemuDomainAsyncJob asyncJob,
+                              qemuMonitorMigrationStatsPtr stats)
+{
+    size_t i;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    bool nbd = false;
+    virHashTablePtr blockinfo = NULL;
+
+    for (i = 0; i < vm->def->ndisks; i++) {
+        virDomainDiskDefPtr disk = vm->def->disks[i];
+        if (QEMU_DOMAIN_DISK_PRIVATE(disk)->migrating) {
+            nbd = true;
+            break;
+        }
+    }
+
+    if (!nbd)
+        return 0;
+
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+        return -1;
+
+    blockinfo = qemuMonitorGetAllBlockJobInfo(priv->mon);
+
+    if (qemuDomainObjExitMonitor(driver, vm) < 0 || !blockinfo)
+        return -1;
+
+    stats->disk_transferred = 0;
+    stats->disk_total = 0;
+    stats->disk_remaining = 0;
+
+    for (i = 0; i < vm->def->ndisks; i++) {
+        virDomainDiskDefPtr disk = vm->def->disks[i];
+        qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
+        qemuMonitorBlockJobInfoPtr data;
+
+        if (!diskPriv->migrating)
+            continue;
+
+        if (!(data = virHashLookup(blockinfo, disk->info.alias)))
+            continue;
+
+        stats->disk_transferred += data->cur;
+        stats->disk_total += data->end;
+        stats->disk_remaining += data->end - data->cur;
+    }
+
+    virHashFree(blockinfo);
+    return 0;
+}
 
 static const char *
 qemuMigrationJobName(virDomainObjPtr vm)
@@ -2768,6 +2821,8 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver,
     }
 
     qemuDomainJobInfoUpdateTime(jobInfo);
+    qemuMigrationFetchMirrorStats(driver, vm, asyncJob, &jobInfo->stats);
+
     qemuDomainJobInfoUpdateDowntime(jobInfo);
     VIR_FREE(priv->job.completed);
     if (VIR_ALLOC(priv->job.completed) == 0)
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index 9293859..5f60a9b 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -245,6 +245,11 @@ int qemuMigrationToFile(virQEMUDriverPtr driver,
 int qemuMigrationCancel(virQEMUDriverPtr driver,
                         virDomainObjPtr vm);
 
+int qemuMigrationFetchMirrorStats(virQEMUDriverPtr driver,
+                                  virDomainObjPtr vm,
+                                  qemuDomainAsyncJob asyncJob,
+                                  qemuMonitorMigrationStatsPtr stats);
+
 int qemuMigrationErrorInit(virQEMUDriverPtr driver);
 void qemuMigrationErrorSave(virQEMUDriverPtr driver,
                             const char *name,
-- 
1.8.3.1




More information about the libvir-list mailing list