[libvirt] [PATCH v4 12/13] qemu: migrate: add mirror stats to migration stats

Nikolay Shirokovskiy nshirokovskiy at virtuozzo.com
Fri Sep 1 06:49:30 UTC 2017


When getting job info in case mirror does not reach ready phase
fetch mirror stats from qemu. Otherwise mirror stats are already
saved in current job.
---
 src/qemu/qemu_domain.c    | 31 +++++++++++++++++++--------
 src/qemu/qemu_domain.h    |  9 ++++++++
 src/qemu/qemu_driver.c    |  5 +++++
 src/qemu/qemu_migration.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_migration.h |  6 ++++++
 5 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 4a678aa..38ccd99 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -448,9 +448,13 @@ qemuDomainJobInfoToInfo(qemuDomainJobInfoPtr jobInfo,
     info->memRemaining = jobInfo->stats.ram_remaining;
     info->memProcessed = jobInfo->stats.ram_transferred;
 
-    info->fileTotal = jobInfo->stats.disk_total;
-    info->fileRemaining = jobInfo->stats.disk_remaining;
-    info->fileProcessed = jobInfo->stats.disk_transferred;
+    info->fileTotal = jobInfo->stats.disk_total +
+                      jobInfo->mirrorStats.total;
+    info->fileRemaining = jobInfo->stats.disk_remaining +
+                          (jobInfo->mirrorStats.total -
+                           jobInfo->mirrorStats.transferred);
+    info->fileProcessed = jobInfo->stats.disk_transferred +
+                          jobInfo->mirrorStats.transferred;
 
     info->dataTotal = info->memTotal + info->fileTotal;
     info->dataRemaining = info->memRemaining + info->fileRemaining;
@@ -466,9 +470,12 @@ qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
                           int *nparams)
 {
     qemuMonitorMigrationStats *stats = &jobInfo->stats;
+    qemuDomainMirrorStatsPtr mirrorStats = &jobInfo->mirrorStats;
     virTypedParameterPtr par = NULL;
     int maxpar = 0;
     int npar = 0;
+    unsigned long long mirrorRemaining = mirrorStats->total -
+                                         mirrorStats->transferred;
 
     if (virTypedParamsAddInt(&par, &npar, &maxpar,
                              VIR_DOMAIN_JOB_OPERATION,
@@ -510,15 +517,18 @@ qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
     if (virTypedParamsAddULLong(&par, &npar, &maxpar,
                                 VIR_DOMAIN_JOB_DATA_TOTAL,
                                 stats->ram_total +
-                                stats->disk_total) < 0 ||
+                                stats->disk_total +
+                                mirrorStats->total) < 0 ||
         virTypedParamsAddULLong(&par, &npar, &maxpar,
                                 VIR_DOMAIN_JOB_DATA_PROCESSED,
                                 stats->ram_transferred +
-                                stats->disk_transferred) < 0 ||
+                                stats->disk_transferred +
+                                mirrorStats->transferred) < 0 ||
         virTypedParamsAddULLong(&par, &npar, &maxpar,
                                 VIR_DOMAIN_JOB_DATA_REMAINING,
                                 stats->ram_remaining +
-                                stats->disk_remaining) < 0)
+                                stats->disk_remaining +
+                                mirrorRemaining) < 0)
         goto error;
 
     if (virTypedParamsAddULLong(&par, &npar, &maxpar,
@@ -561,13 +571,16 @@ qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
 
     if (virTypedParamsAddULLong(&par, &npar, &maxpar,
                                 VIR_DOMAIN_JOB_DISK_TOTAL,
-                                stats->disk_total) < 0 ||
+                                stats->disk_total +
+                                mirrorStats->total) < 0 ||
         virTypedParamsAddULLong(&par, &npar, &maxpar,
                                 VIR_DOMAIN_JOB_DISK_PROCESSED,
-                                stats->disk_transferred) < 0 ||
+                                stats->disk_transferred +
+                                mirrorStats->transferred) < 0 ||
         virTypedParamsAddULLong(&par, &npar, &maxpar,
                                 VIR_DOMAIN_JOB_DISK_REMAINING,
-                                stats->disk_remaining) < 0)
+                                stats->disk_remaining +
+                                mirrorRemaining) < 0)
         goto error;
 
     if (stats->disk_bps &&
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index f6d99b7..834fa8e 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -109,6 +109,14 @@ typedef enum {
     QEMU_DOMAIN_JOB_STATUS_CANCELED,
 } qemuDomainJobStatus;
 
+
+typedef struct _qemuDomainMirrorStats qemuDomainMirrorStats;
+typedef qemuDomainMirrorStats *qemuDomainMirrorStatsPtr;
+struct _qemuDomainMirrorStats {
+    unsigned long long transferred;
+    unsigned long long total;
+};
+
 typedef struct _qemuDomainJobInfo qemuDomainJobInfo;
 typedef qemuDomainJobInfo *qemuDomainJobInfoPtr;
 struct _qemuDomainJobInfo {
@@ -130,6 +138,7 @@ struct _qemuDomainJobInfo {
     bool timeDeltaSet;
     /* Raw values from QEMU */
     qemuMonitorMigrationStats stats;
+    qemuDomainMirrorStats mirrorStats;
 };
 
 struct qemuDomainJobObj {
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 11226b1..4b7f6a7 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13028,6 +13028,11 @@ qemuDomainGetJobStatsInternal(virQEMUDriverPtr driver,
             qemuMigrationFetchStats(driver, vm, QEMU_ASYNC_JOB_NONE, jobInfo) < 0)
             goto cleanup;
 
+        if (jobInfo->status == QEMU_DOMAIN_JOB_STATUS_ACTIVE &&
+            qemuMigrationFetchMirrorStats(driver, vm, QEMU_ASYNC_JOB_NONE,
+                                          jobInfo) < 0)
+            goto cleanup;
+
         if (qemuDomainJobInfoUpdateTime(jobInfo) < 0)
             goto cleanup;
     }
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index e48ad2d..3e66596 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -983,6 +983,9 @@ qemuMigrationDriveMirror(virQEMUDriverPtr driver,
             goto cleanup;
     }
 
+    qemuMigrationFetchMirrorStats(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT,
+                                  priv->job.current);
+
     /* Okay, all disks are ready. Modify migrate_flags */
     *migrate_flags &= ~(QEMU_MONITOR_MIGRATE_NON_SHARED_DISK |
                         QEMU_MONITOR_MIGRATE_NON_SHARED_INC);
@@ -5918,3 +5921,54 @@ qemuMigrationReset(virQEMUDriverPtr driver,
         virFreeError(err);
     }
 }
+
+
+int
+qemuMigrationFetchMirrorStats(virQEMUDriverPtr driver,
+                              virDomainObjPtr vm,
+                              qemuDomainAsyncJob asyncJob,
+                              qemuDomainJobInfoPtr jobInfo)
+{
+    size_t i;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    bool nbd = false;
+    virHashTablePtr blockinfo = NULL;
+    qemuDomainMirrorStatsPtr stats = &jobInfo->mirrorStats;
+
+    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;
+
+    memset(stats, 0, sizeof(*stats));
+
+    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 ||
+            !(data = virHashLookup(blockinfo, disk->info.alias)))
+            continue;
+
+        stats->transferred += data->cur;
+        stats->total += data->end;
+    }
+
+    virHashFree(blockinfo);
+    return 0;
+}
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index ecb693c..57c7479 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -319,4 +319,10 @@ qemuMigrationReset(virQEMUDriverPtr driver,
                    virDomainObjPtr vm,
                    qemuDomainAsyncJob job);
 
+int
+qemuMigrationFetchMirrorStats(virQEMUDriverPtr driver,
+                              virDomainObjPtr vm,
+                              qemuDomainAsyncJob asyncJob,
+                              qemuDomainJobInfoPtr jobInfo);
+
 #endif /* __QEMU_MIGRATION_H__ */
-- 
1.8.3.1




More information about the libvir-list mailing list