[libvirt] [PATCH 08/14] qemu: Parse more fields from query-migrate QMP command

Jiri Denemark jdenemar at redhat.com
Tue Feb 19 12:35:46 UTC 2013


As a side effect, this also fixes reporting disk migration process.
It was added to memory migration progress, which was wrong. Disk
progress has dedicated fields in virDomainJobInfo structure.
---
 src/qemu/qemu_domain.c       |   1 +
 src/qemu/qemu_domain.h       |   3 +-
 src/qemu/qemu_migration.c    |  44 +++++++------
 src/qemu/qemu_monitor.c      |  15 +----
 src/qemu/qemu_monitor.h      |  34 ++++++++--
 src/qemu/qemu_monitor_json.c | 150 ++++++++++++++++++++++++++++++-------------
 src/qemu/qemu_monitor_json.h |   5 +-
 src/qemu/qemu_monitor_text.c |  47 +++++++-------
 src/qemu/qemu_monitor_text.h |   5 +-
 9 files changed, 192 insertions(+), 112 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 482f64a..eca85fc 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -160,6 +160,7 @@ qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv)
     job->start = 0;
     job->dump_memory_only = false;
     job->asyncAbort = false;
+    memset(&job->status, 0, sizeof(job->status));
     memset(&job->info, 0, sizeof(job->info));
 }
 
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index c9d5f8b..e4fb2f6 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -110,7 +110,8 @@ struct qemuDomainJobObj {
     unsigned long long mask;            /* Jobs allowed during async job */
     unsigned long long start;           /* When the async job started */
     bool dump_memory_only;              /* use dump-guest-memory to do dump */
-    virDomainJobInfo info;              /* Async job progress data */
+    qemuMonitorMigrationStatus status;  /* Raw async job progress data */
+    virDomainJobInfo info;              /* Processed async job progress data */
     bool asyncAbort;                    /* abort of async job requested */
 };
 
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index de8dfec..4142872 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1198,12 +1198,11 @@ qemuMigrationUpdateJobStatus(virQEMUDriverPtr driver,
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     int ret;
-    int status;
     bool wait_for_spice = false;
     bool spice_migrated = false;
-    unsigned long long memProcessed;
-    unsigned long long memRemaining;
-    unsigned long long memTotal;
+    qemuMonitorMigrationStatus status;
+
+    memset(&status, 0, sizeof(status));
 
     /* If guest uses SPICE and supports seamles_migration we have to hold up
      * migration finish until SPICE server transfers its data */
@@ -1217,20 +1216,19 @@ qemuMigrationUpdateJobStatus(virQEMUDriverPtr driver,
         /* Guest already exited; nothing further to update.  */
         return -1;
     }
-    ret = qemuMonitorGetMigrationStatus(priv->mon,
-                                        &status,
-                                        &memProcessed,
-                                        &memRemaining,
-                                        &memTotal);
+    ret = qemuMonitorGetMigrationStatus(priv->mon, &status);
 
     /* If qemu says migrated, check spice */
-    if (wait_for_spice && (ret == 0) &&
-        (status == QEMU_MONITOR_MIGRATION_STATUS_COMPLETED))
+    if (wait_for_spice &&
+        ret == 0 &&
+        status.status == QEMU_MONITOR_MIGRATION_STATUS_COMPLETED)
         ret = qemuMonitorGetSpiceMigrationStatus(priv->mon,
                                                  &spice_migrated);
 
     qemuDomainObjExitMonitor(driver, vm);
 
+    priv->job.status = status;
+
     if (ret < 0 || virTimeMillisNow(&priv->job.info.timeElapsed) < 0) {
         priv->job.info.type = VIR_DOMAIN_JOB_FAILED;
         return -1;
@@ -1238,7 +1236,7 @@ qemuMigrationUpdateJobStatus(virQEMUDriverPtr driver,
     priv->job.info.timeElapsed -= priv->job.start;
 
     ret = -1;
-    switch (status) {
+    switch (priv->job.status.status) {
     case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE:
         priv->job.info.type = VIR_DOMAIN_JOB_NONE;
         virReportError(VIR_ERR_OPERATION_FAILED,
@@ -1246,13 +1244,21 @@ qemuMigrationUpdateJobStatus(virQEMUDriverPtr driver,
         break;
 
     case QEMU_MONITOR_MIGRATION_STATUS_ACTIVE:
-        priv->job.info.dataTotal = memTotal;
-        priv->job.info.dataRemaining = memRemaining;
-        priv->job.info.dataProcessed = memProcessed;
-
-        priv->job.info.memTotal = memTotal;
-        priv->job.info.memRemaining = memRemaining;
-        priv->job.info.memProcessed = memProcessed;
+        priv->job.info.fileTotal = priv->job.status.disk_total;
+        priv->job.info.fileRemaining = priv->job.status.disk_remaining;
+        priv->job.info.fileProcessed = priv->job.status.disk_transferred;
+
+        priv->job.info.memTotal = priv->job.status.ram_total;
+        priv->job.info.memRemaining = priv->job.status.ram_remaining;
+        priv->job.info.memProcessed = priv->job.status.ram_transferred;
+
+        priv->job.info.dataTotal =
+            priv->job.status.ram_total + priv->job.status.disk_total;
+        priv->job.info.dataRemaining =
+            priv->job.status.ram_remaining + priv->job.status.disk_remaining;
+        priv->job.info.dataProcessed =
+            priv->job.status.ram_transferred +
+            priv->job.status.disk_transferred;
 
         ret = 0;
         break;
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 631ff92..21489fb 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1805,10 +1805,7 @@ int qemuMonitorSetMigrationDowntime(qemuMonitorPtr mon,
 
 
 int qemuMonitorGetMigrationStatus(qemuMonitorPtr mon,
-                                  int *status,
-                                  unsigned long long *transferred,
-                                  unsigned long long *remaining,
-                                  unsigned long long *total)
+                                  qemuMonitorMigrationStatusPtr status)
 {
     int ret;
     VIR_DEBUG("mon=%p", mon);
@@ -1820,15 +1817,9 @@ int qemuMonitorGetMigrationStatus(qemuMonitorPtr mon,
     }
 
     if (mon->json)
-        ret = qemuMonitorJSONGetMigrationStatus(mon, status,
-                                                transferred,
-                                                remaining,
-                                                total);
+        ret = qemuMonitorJSONGetMigrationStatus(mon, status);
     else
-        ret = qemuMonitorTextGetMigrationStatus(mon, status,
-                                                transferred,
-                                                remaining,
-                                                total);
+        ret = qemuMonitorTextGetMigrationStatus(mon, status);
     return ret;
 }
 
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index e3a4568..40e635d 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -338,11 +338,37 @@ enum {
 
 VIR_ENUM_DECL(qemuMonitorMigrationStatus)
 
+typedef struct _qemuMonitorMigrationStatus qemuMonitorMigrationStatus;
+typedef qemuMonitorMigrationStatus *qemuMonitorMigrationStatusPtr;
+struct _qemuMonitorMigrationStatus {
+    int status;
+    unsigned long long total_time;
+    /* total or expected depending on status */
+    bool downtime_set;
+    unsigned long long downtime;
+
+    unsigned long long ram_transferred;
+    unsigned long long ram_remaining;
+    unsigned long long ram_total;
+    bool ram_duplicate_set;
+    unsigned long long ram_duplicate;
+    unsigned long long ram_normal;
+    unsigned long long ram_normal_bytes;
+
+    unsigned long long disk_transferred;
+    unsigned long long disk_remaining;
+    unsigned long long disk_total;
+
+    bool xbzrle_set;
+    unsigned long long xbzrle_cache_size;
+    unsigned long long xbzrle_bytes;
+    unsigned long long xbzrle_pages;
+    unsigned long long xbzrle_cache_miss;
+    unsigned long long xbzrle_overflow;
+};
+
 int qemuMonitorGetMigrationStatus(qemuMonitorPtr mon,
-                                  int *status,
-                                  unsigned long long *transferred,
-                                  unsigned long long *remaining,
-                                  unsigned long long *total);
+                                  qemuMonitorMigrationStatusPtr status);
 int qemuMonitorGetSpiceMigrationStatus(qemuMonitorPtr mon,
                                        bool *spice_migrated);
 
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 545d4d4..e8c1f81 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2258,14 +2258,11 @@ int qemuMonitorJSONSetMigrationDowntime(qemuMonitorPtr mon,
 
 static int
 qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
-                                       int *status,
-                                       unsigned long long *transferred,
-                                       unsigned long long *remaining,
-                                       unsigned long long *total)
+                                       qemuMonitorMigrationStatusPtr status)
 {
     virJSONValuePtr ret;
     const char *statusstr;
-    unsigned long long t;
+    int rc;
 
     if (!(ret = virJSONValueObjectGet(reply, "return"))) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -2279,13 +2276,25 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
         return -1;
     }
 
-    if ((*status = qemuMonitorMigrationStatusTypeFromString(statusstr)) < 0) {
+    status->status = qemuMonitorMigrationStatusTypeFromString(statusstr);
+    if (status->status < 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("unexpected migration status in %s"), statusstr);
         return -1;
     }
 
-    if (*status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE) {
+    virJSONValueObjectGetNumberUlong(ret, "total-time", &status->total_time);
+    if (status->status == QEMU_MONITOR_MIGRATION_STATUS_COMPLETED) {
+        rc = virJSONValueObjectGetNumberUlong(ret, "downtime",
+                                              &status->downtime);
+    } else {
+        rc = virJSONValueObjectGetNumberUlong(ret, "expected-downtime",
+                                              &status->downtime);
+    }
+    if (rc == 0)
+        status->downtime_set = true;
+
+    if (status->status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE) {
         virJSONValuePtr ram = virJSONValueObjectGet(ret, "ram");
         if (!ram) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -2294,51 +2303,112 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
         }
 
         if (virJSONValueObjectGetNumberUlong(ram, "transferred",
-                                             transferred) < 0) {
+                                             &status->ram_transferred) < 0) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("migration was active, but RAM 'transferred' "
                              "data was missing"));
             return -1;
         }
-        if (virJSONValueObjectGetNumberUlong(ram, "remaining", remaining) < 0) {
+        if (virJSONValueObjectGetNumberUlong(ram, "remaining",
+                                             &status->ram_remaining) < 0) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("migration was active, but RAM 'remaining' "
                              "data was missing"));
             return -1;
         }
-        if (virJSONValueObjectGetNumberUlong(ram, "total", total) < 0) {
+        if (virJSONValueObjectGetNumberUlong(ram, "total",
+                                             &status->ram_total) < 0) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("migration was active, but RAM 'total' "
                              "data was missing"));
             return -1;
         }
 
+        if (virJSONValueObjectGetNumberUlong(ram, "duplicate",
+                                             &status->ram_duplicate) == 0)
+            status->ram_duplicate_set = true;
+        virJSONValueObjectGetNumberUlong(ram, "normal", &status->ram_normal);
+        virJSONValueObjectGetNumberUlong(ram, "normal-bytes",
+                                         &status->ram_normal_bytes);
+
         virJSONValuePtr disk = virJSONValueObjectGet(ret, "disk");
-        if (!disk) {
-            return 0;
-        }
+        if (disk) {
+            rc = virJSONValueObjectGetNumberUlong(disk, "transferred",
+                                                  &status->disk_transferred);
+            if (rc < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("disk migration was active, but "
+                                 "'transferred' data was missing"));
+                return -1;
+            }
 
-        if (virJSONValueObjectGetNumberUlong(disk, "transferred", &t) < 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("disk migration was active, but 'transferred' "
-                             "data was missing"));
-            return -1;
-        }
-        *transferred += t;
-        if (virJSONValueObjectGetNumberUlong(disk, "remaining", &t) < 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("disk migration was active, but 'remaining' "
-                             "data was missing"));
-            return -1;
+            rc = virJSONValueObjectGetNumberUlong(disk, "remaining",
+                                                  &status->disk_remaining);
+            if (rc < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("disk migration was active, but 'remaining' "
+                                 "data was missing"));
+                return -1;
+            }
+
+            rc = virJSONValueObjectGetNumberUlong(disk, "total",
+                                                  &status->disk_total);
+            if (rc < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("disk migration was active, but 'total' "
+                                 "data was missing"));
+                return -1;
+            }
         }
-        *remaining += t;
-        if (virJSONValueObjectGetNumberUlong(disk, "total", &t) < 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("disk migration was active, but 'total' "
-                             "data was missing"));
-            return -1;
+
+        virJSONValuePtr comp = virJSONValueObjectGet(ret, "xbzrle-cache");
+        if (comp) {
+            status->xbzrle_set = true;
+            rc = virJSONValueObjectGetNumberUlong(comp, "cache-size",
+                                                  &status->xbzrle_cache_size);
+            if (rc < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("XBZRLE is active, but 'cache-size' data "
+                                 "was missing"));
+                return -1;
+            }
+
+            rc = virJSONValueObjectGetNumberUlong(comp, "bytes",
+                                                  &status->xbzrle_bytes);
+            if (rc < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("XBZRLE is active, but 'bytes' data "
+                                 "was missing"));
+                return -1;
+            }
+
+            rc = virJSONValueObjectGetNumberUlong(comp, "pages",
+                                                  &status->xbzrle_pages);
+            if (rc < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("XBZRLE is active, but 'pages' data "
+                                 "was missing"));
+                return -1;
+            }
+
+            rc = virJSONValueObjectGetNumberUlong(comp, "cache-miss",
+                                                  &status->xbzrle_cache_miss);
+            if (rc < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("XBZRLE is active, but 'cache-miss' data "
+                                 "was missing"));
+                return -1;
+            }
+
+            rc = virJSONValueObjectGetNumberUlong(comp, "overflow",
+                                                  &status->xbzrle_overflow);
+            if (rc < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("XBZRLE is active, but 'overflow' data "
+                                 "was missing"));
+                return -1;
+            }
         }
-        *total += t;
     }
 
     return 0;
@@ -2346,18 +2416,14 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
 
 
 int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon,
-                                      int *status,
-                                      unsigned long long *transferred,
-                                      unsigned long long *remaining,
-                                      unsigned long long *total)
+                                      qemuMonitorMigrationStatusPtr status)
 {
     int ret;
     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-migrate",
                                                      NULL);
     virJSONValuePtr reply = NULL;
 
-    *status = 0;
-    *transferred = *remaining = *total = 0;
+    memset(status, 0, sizeof(*status));
 
     if (!cmd)
         return -1;
@@ -2368,13 +2434,11 @@ int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon,
         ret = qemuMonitorJSONCheckError(cmd, reply);
 
     if (ret == 0 &&
-        qemuMonitorJSONGetMigrationStatusReply(reply,
-                                               status,
-                                               transferred,
-                                               remaining,
-                                               total) < 0)
+        qemuMonitorJSONGetMigrationStatusReply(reply, status) < 0)
         ret = -1;
 
+    if (ret < 0)
+        memset(status, 0, sizeof(*status));
     virJSONValueFree(cmd);
     virJSONValueFree(reply);
     return ret;
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 356c10a..66635fd 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -121,10 +121,7 @@ int qemuMonitorJSONSetMigrationDowntime(qemuMonitorPtr mon,
                                         unsigned long long downtime);
 
 int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon,
-                                      int *status,
-                                      unsigned long long *transferred,
-                                      unsigned long long *remaining,
-                                      unsigned long long *total);
+                                      qemuMonitorMigrationStatusPtr status);
 
 int qemuMonitorJSONGetMigrationCapability(qemuMonitorPtr mon,
                                           qemuMonitorMigrationCaps capability);
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index bc0a11d..58f6323 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -1474,22 +1474,14 @@ cleanup:
 #define MIGRATION_DISK_TOTAL_PREFIX "total disk: "
 
 int qemuMonitorTextGetMigrationStatus(qemuMonitorPtr mon,
-                                      int *status,
-                                      unsigned long long *transferred,
-                                      unsigned long long *remaining,
-                                      unsigned long long *total) {
+                                      qemuMonitorMigrationStatusPtr status)
+{
     char *reply;
     char *tmp;
     char *end;
-    unsigned long long disk_transferred = 0;
-    unsigned long long disk_remaining = 0;
-    unsigned long long disk_total = 0;
     int ret = -1;
 
-    *status = QEMU_MONITOR_MIGRATION_STATUS_INACTIVE;
-    *transferred = 0;
-    *remaining = 0;
-    *total = 0;
+    memset(status, 0, sizeof(*status));
 
     if (qemuMonitorHMPCommand(mon, "info migrate", &reply) < 0)
         return -1;
@@ -1504,52 +1496,54 @@ int qemuMonitorTextGetMigrationStatus(qemuMonitorPtr mon,
         }
         *end = '\0';
 
-        if ((*status = qemuMonitorMigrationStatusTypeFromString(tmp)) < 0) {
+        status->status = qemuMonitorMigrationStatusTypeFromString(tmp);
+        if (status->status < 0) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("unexpected migration status in %s"), reply);
             goto cleanup;
         }
 
-        if (*status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE) {
+        if (status->status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE) {
             tmp = end + 1;
 
             if (!(tmp = strstr(tmp, MIGRATION_TRANSFER_PREFIX)))
                 goto done;
             tmp += strlen(MIGRATION_TRANSFER_PREFIX);
 
-            if (virStrToLong_ull(tmp, &end, 10, transferred) < 0) {
+            if (virStrToLong_ull(tmp, &end, 10,
+                                 &status->ram_transferred) < 0) {
                 virReportError(VIR_ERR_INTERNAL_ERROR,
                                _("cannot parse migration data transferred "
                                  "statistic %s"), tmp);
                 goto cleanup;
             }
-            *transferred *= 1024;
+            status->ram_transferred *= 1024;
             tmp = end;
 
             if (!(tmp = strstr(tmp, MIGRATION_REMAINING_PREFIX)))
                 goto done;
             tmp += strlen(MIGRATION_REMAINING_PREFIX);
 
-            if (virStrToLong_ull(tmp, &end, 10, remaining) < 0) {
+            if (virStrToLong_ull(tmp, &end, 10, &status->ram_remaining) < 0) {
                 virReportError(VIR_ERR_INTERNAL_ERROR,
                                _("cannot parse migration data remaining "
                                  "statistic %s"), tmp);
                 goto cleanup;
             }
-            *remaining *= 1024;
+            status->ram_remaining *= 1024;
             tmp = end;
 
             if (!(tmp = strstr(tmp, MIGRATION_TOTAL_PREFIX)))
                 goto done;
             tmp += strlen(MIGRATION_TOTAL_PREFIX);
 
-            if (virStrToLong_ull(tmp, &end, 10, total) < 0) {
+            if (virStrToLong_ull(tmp, &end, 10, &status->ram_total) < 0) {
                 virReportError(VIR_ERR_INTERNAL_ERROR,
                                _("cannot parse migration data total "
                                  "statistic %s"), tmp);
                 goto cleanup;
             }
-            *total *= 1024;
+            status->ram_total *= 1024;
             tmp = end;
 
             /*
@@ -1559,39 +1553,40 @@ int qemuMonitorTextGetMigrationStatus(qemuMonitorPtr mon,
                 goto done;
             tmp += strlen(MIGRATION_DISK_TRANSFER_PREFIX);
 
-            if (virStrToLong_ull(tmp, &end, 10, &disk_transferred) < 0) {
+            if (virStrToLong_ull(tmp, &end, 10,
+                                 &status->disk_transferred) < 0) {
                 virReportError(VIR_ERR_INTERNAL_ERROR,
                                _("cannot parse disk migration data "
                                  "transferred statistic %s"), tmp);
                 goto cleanup;
             }
-            *transferred += disk_transferred * 1024;
+            status->disk_transferred *= 1024;
             tmp = end;
 
             if (!(tmp = strstr(tmp, MIGRATION_DISK_REMAINING_PREFIX)))
                 goto done;
             tmp += strlen(MIGRATION_DISK_REMAINING_PREFIX);
 
-            if (virStrToLong_ull(tmp, &end, 10, &disk_remaining) < 0) {
+            if (virStrToLong_ull(tmp, &end, 10, &status->disk_remaining) < 0) {
                 virReportError(VIR_ERR_INTERNAL_ERROR,
                                _("cannot parse disk migration data remaining "
                                  "statistic %s"), tmp);
                 goto cleanup;
             }
-            *remaining += disk_remaining * 1024;
+            status->disk_remaining *= 1024;
             tmp = end;
 
             if (!(tmp = strstr(tmp, MIGRATION_DISK_TOTAL_PREFIX)))
                 goto done;
             tmp += strlen(MIGRATION_DISK_TOTAL_PREFIX);
 
-            if (virStrToLong_ull(tmp, &end, 10, &disk_total) < 0) {
+            if (virStrToLong_ull(tmp, &end, 10, &status->disk_total) < 0) {
                 virReportError(VIR_ERR_INTERNAL_ERROR,
                                _("cannot parse disk migration data total "
                                  "statistic %s"), tmp);
                 goto cleanup;
             }
-            *total += disk_total * 1024;
+            status->disk_total *= 1024;
         }
     }
 
@@ -1600,6 +1595,8 @@ done:
 
 cleanup:
     VIR_FREE(reply);
+    if (ret < 0)
+        memset(status, 0, sizeof(*status));
     return ret;
 }
 
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index 97abad6..fb8e904 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -117,10 +117,7 @@ int qemuMonitorTextSetMigrationDowntime(qemuMonitorPtr mon,
                                         unsigned long long downtime);
 
 int qemuMonitorTextGetMigrationStatus(qemuMonitorPtr mon,
-                                      int *status,
-                                      unsigned long long *transferred,
-                                      unsigned long long *remaining,
-                                      unsigned long long *total);
+                                      qemuMonitorMigrationStatusPtr status);
 
 int qemuMonitorTextMigrate(qemuMonitorPtr mon,
                            unsigned int flags,
-- 
1.8.1.2




More information about the libvir-list mailing list