9119d9
From b7beeafeb8008afc50bce60e9c5c31786a5c6e2e Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <b7beeafeb8008afc50bce60e9c5c31786a5c6e2e@dist-git>
9119d9
From: "Michael R. Hines" <mrhines@us.ibm.com>
9119d9
Date: Tue, 23 Sep 2014 15:47:53 +0200
9119d9
Subject: [PATCH] qemu: Expose additional migration statistics
9119d9
9119d9
RDMA migration uses the 'setup' state in QEMU to optionally lock
9119d9
all memory before the migration starts. The total time spent in
9119d9
this state is exposed as VIR_DOMAIN_JOB_SETUP_TIME.
9119d9
9119d9
Additionally, QEMU also exports migration throughput (mbps) for both
9119d9
memory and disk, so let's add them too: VIR_DOMAIN_JOB_MEMORY_BPS,
9119d9
VIR_DOMAIN_JOB_DISK_BPS.
9119d9
9119d9
https://bugzilla.redhat.com/show_bug.cgi?id=1013055
9119d9
9119d9
Signed-off-by: Michael R. Hines <mrhines@us.ibm.com>
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
(cherry picked from commit 30b24df16574997d2857c705148932f793d82896)
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
---
9119d9
 include/libvirt/libvirt.h.in | 25 +++++++++++++++++++++++++
9119d9
 src/qemu/qemu_domain.c       | 18 ++++++++++++++++++
9119d9
 src/qemu/qemu_migration.c    | 17 +++++++++++++++++
9119d9
 src/qemu/qemu_monitor.h      |  9 +++++++++
9119d9
 src/qemu/qemu_monitor_json.c | 17 +++++++++++++++++
9119d9
 tools/virsh-domain.c         | 27 +++++++++++++++++++++++++++
9119d9
 6 files changed, 113 insertions(+)
9119d9
9119d9
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
9119d9
index ec2fb8c..b07797e 100644
9119d9
--- a/include/libvirt/libvirt.h.in
9119d9
+++ b/include/libvirt/libvirt.h.in
9119d9
@@ -4357,6 +4357,15 @@ int virDomainAbortJob(virDomainPtr dom);
9119d9
 #define VIR_DOMAIN_JOB_DOWNTIME                 "downtime"
9119d9
 
9119d9
 /**
9119d9
+ * VIR_DOMAIN_JOB_SETUP_TIME:
9119d9
+ *
9119d9
+ * virDomainGetJobStats field: total time in milliseconds spent preparing
9119d9
+ * the migration in the 'setup' phase before the iterations begin, as
9119d9
+ * VIR_TYPED_PARAM_ULLONG.
9119d9
+ */
9119d9
+#define VIR_DOMAIN_JOB_SETUP_TIME               "setup_time"
9119d9
+
9119d9
+/**
9119d9
  * VIR_DOMAIN_JOB_DATA_TOTAL:
9119d9
  *
9119d9
  * virDomainGetJobStats field: total number of bytes supposed to be
9119d9
@@ -4454,6 +4463,14 @@ int virDomainAbortJob(virDomainPtr dom);
9119d9
 #define VIR_DOMAIN_JOB_MEMORY_NORMAL_BYTES      "memory_normal_bytes"
9119d9
 
9119d9
 /**
9119d9
+ * VIR_DOMAIN_JOB_MEMORY_BPS:
9119d9
+ *
9119d9
+ * virDomainGetJobStats field: network throughput used while migrating
9119d9
+ * memory in Bytes per second, as VIR_TYPED_PARAM_ULLONG.
9119d9
+ */
9119d9
+#define VIR_DOMAIN_JOB_MEMORY_BPS               "memory_bps"
9119d9
+
9119d9
+/**
9119d9
  * VIR_DOMAIN_JOB_DISK_TOTAL:
9119d9
  *
9119d9
  * virDomainGetJobStats field: as VIR_DOMAIN_JOB_DATA_TOTAL but only
9119d9
@@ -4484,6 +4501,14 @@ int virDomainAbortJob(virDomainPtr dom);
9119d9
 #define VIR_DOMAIN_JOB_DISK_REMAINING           "disk_remaining"
9119d9
 
9119d9
 /**
9119d9
+ * VIR_DOMAIN_JOB_DISK_BPS:
9119d9
+ *
9119d9
+ * virDomainGetJobStats field: network throughput used while migrating
9119d9
+ * disks in Bytes per second, as VIR_TYPED_PARAM_ULLONG.
9119d9
+ */
9119d9
+#define VIR_DOMAIN_JOB_DISK_BPS                 "disk_bps"
9119d9
+
9119d9
+/**
9119d9
  * VIR_DOMAIN_JOB_COMPRESSION_CACHE:
9119d9
  *
9119d9
  * virDomainGetJobStats field: size of the cache (in bytes) used for
9119d9
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
9119d9
index 863ab09..9b3edd7 100644
9119d9
--- a/src/qemu/qemu_domain.c
9119d9
+++ b/src/qemu/qemu_domain.c
9119d9
@@ -304,6 +304,12 @@ qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
9119d9
                                 status->downtime) < 0)
9119d9
         goto error;
9119d9
 
9119d9
+    if (status->setup_time_set &&
9119d9
+        virTypedParamsAddULLong(&par, &npar, &maxpar,
9119d9
+                                VIR_DOMAIN_JOB_SETUP_TIME,
9119d9
+                                status->setup_time) < 0)
9119d9
+        goto error;
9119d9
+
9119d9
     if (virTypedParamsAddULLong(&par, &npar, &maxpar,
9119d9
                                 VIR_DOMAIN_JOB_DATA_TOTAL,
9119d9
                                 status->ram_total +
9119d9
@@ -329,6 +335,12 @@ qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
9119d9
                                 status->ram_remaining) < 0)
9119d9
         goto error;
9119d9
 
9119d9
+    if (status->ram_bps &&
9119d9
+        virTypedParamsAddULLong(&par, &npar, &maxpar,
9119d9
+                                VIR_DOMAIN_JOB_MEMORY_BPS,
9119d9
+                                status->ram_bps) < 0)
9119d9
+        goto error;
9119d9
+
9119d9
     if (status->ram_duplicate_set) {
9119d9
         if (virTypedParamsAddULLong(&par, &npar, &maxpar,
9119d9
                                     VIR_DOMAIN_JOB_MEMORY_CONSTANT,
9119d9
@@ -353,6 +365,12 @@ qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
9119d9
                                 status->disk_remaining) < 0)
9119d9
         goto error;
9119d9
 
9119d9
+    if (status->disk_bps &&
9119d9
+        virTypedParamsAddULLong(&par, &npar, &maxpar,
9119d9
+                                VIR_DOMAIN_JOB_DISK_BPS,
9119d9
+                                status->disk_bps) < 0)
9119d9
+        goto error;
9119d9
+
9119d9
     if (status->xbzrle_set) {
9119d9
         if (virTypedParamsAddULLong(&par, &npar, &maxpar,
9119d9
                                     VIR_DOMAIN_JOB_COMPRESSION_CACHE,
9119d9
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
9119d9
index 858794d..179af80 100644
9119d9
--- a/src/qemu/qemu_migration.c
9119d9
+++ b/src/qemu/qemu_migration.c
9119d9
@@ -636,6 +636,10 @@ qemuMigrationCookieStatisticsXMLFormat(virBufferPtr buf,
9119d9
         virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
                           VIR_DOMAIN_JOB_DOWNTIME,
9119d9
                           status->downtime);
9119d9
+    if (status->setup_time_set)
9119d9
+        virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                          VIR_DOMAIN_JOB_SETUP_TIME,
9119d9
+                          status->setup_time);
9119d9
 
9119d9
     virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
                       VIR_DOMAIN_JOB_MEMORY_TOTAL,
9119d9
@@ -646,6 +650,9 @@ qemuMigrationCookieStatisticsXMLFormat(virBufferPtr buf,
9119d9
     virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
                       VIR_DOMAIN_JOB_MEMORY_REMAINING,
9119d9
                       status->ram_remaining);
9119d9
+    virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                      VIR_DOMAIN_JOB_MEMORY_BPS,
9119d9
+                      status->ram_bps);
9119d9
 
9119d9
     if (status->ram_duplicate_set) {
9119d9
         virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
@@ -668,6 +675,9 @@ qemuMigrationCookieStatisticsXMLFormat(virBufferPtr buf,
9119d9
     virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
                       VIR_DOMAIN_JOB_DISK_REMAINING,
9119d9
                       status->disk_remaining);
9119d9
+    virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                      VIR_DOMAIN_JOB_DISK_BPS,
9119d9
+                      status->disk_bps);
9119d9
 
9119d9
     if (status->xbzrle_set) {
9119d9
         virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
@@ -904,6 +914,9 @@ qemuMigrationCookieStatisticsXMLParse(xmlXPathContextPtr ctxt)
9119d9
     if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_DOWNTIME "[1])",
9119d9
                           ctxt, &status->downtime) == 0)
9119d9
         status->downtime_set = true;
9119d9
+    if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_SETUP_TIME "[1])",
9119d9
+                          ctxt, &status->setup_time) == 0)
9119d9
+        status->setup_time_set = true;
9119d9
 
9119d9
     virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_TOTAL "[1])",
9119d9
                       ctxt, &status->ram_total);
9119d9
@@ -911,6 +924,8 @@ qemuMigrationCookieStatisticsXMLParse(xmlXPathContextPtr ctxt)
9119d9
                       ctxt, &status->ram_transferred);
9119d9
     virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_REMAINING "[1])",
9119d9
                       ctxt, &status->ram_remaining);
9119d9
+    virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_BPS "[1])",
9119d9
+                      ctxt, &status->ram_bps);
9119d9
 
9119d9
     if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_CONSTANT "[1])",
9119d9
                           ctxt, &status->ram_duplicate) == 0)
9119d9
@@ -926,6 +941,8 @@ qemuMigrationCookieStatisticsXMLParse(xmlXPathContextPtr ctxt)
9119d9
                       ctxt, &status->disk_transferred);
9119d9
     virXPathULongLong("string(./" VIR_DOMAIN_JOB_DISK_REMAINING "[1])",
9119d9
                       ctxt, &status->disk_remaining);
9119d9
+    virXPathULongLong("string(./" VIR_DOMAIN_JOB_DISK_BPS "[1])",
9119d9
+                      ctxt, &status->disk_bps);
9119d9
 
9119d9
     if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_COMPRESSION_CACHE "[1])",
9119d9
                           ctxt, &status->xbzrle_cache_size) == 0)
9119d9
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
9119d9
index 15aa1d4..ed2cf71 100644
9119d9
--- a/src/qemu/qemu_monitor.h
9119d9
+++ b/src/qemu/qemu_monitor.h
9119d9
@@ -423,10 +423,18 @@ struct _qemuMonitorMigrationStatus {
9119d9
     /* total or expected depending on status */
9119d9
     bool downtime_set;
9119d9
     unsigned long long downtime;
9119d9
+    /*
9119d9
+     * Duration of the QEMU 'setup' state.
9119d9
+     * for RDMA, this may be on the order of several seconds
9119d9
+     * if pinning support is requested before the migration begins.
9119d9
+     */
9119d9
+    bool setup_time_set;
9119d9
+    unsigned long long setup_time;
9119d9
 
9119d9
     unsigned long long ram_transferred;
9119d9
     unsigned long long ram_remaining;
9119d9
     unsigned long long ram_total;
9119d9
+    unsigned long long ram_bps;
9119d9
     bool ram_duplicate_set;
9119d9
     unsigned long long ram_duplicate;
9119d9
     unsigned long long ram_normal;
9119d9
@@ -435,6 +443,7 @@ struct _qemuMonitorMigrationStatus {
9119d9
     unsigned long long disk_transferred;
9119d9
     unsigned long long disk_remaining;
9119d9
     unsigned long long disk_total;
9119d9
+    unsigned long long disk_bps;
9119d9
 
9119d9
     bool xbzrle_set;
9119d9
     unsigned long long xbzrle_cache_size;
9119d9
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
9119d9
index 53e324e..5ad0d05 100644
9119d9
--- a/src/qemu/qemu_monitor_json.c
9119d9
+++ b/src/qemu/qemu_monitor_json.c
9119d9
@@ -2443,6 +2443,7 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
9119d9
     virJSONValuePtr ret;
9119d9
     const char *statusstr;
9119d9
     int rc;
9119d9
+    double mbps;
9119d9
 
9119d9
     if (!(ret = virJSONValueObjectGet(reply, "return"))) {
9119d9
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
9119d9
@@ -2475,6 +2476,10 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
9119d9
     if (rc == 0)
9119d9
         status->downtime_set = true;
9119d9
 
9119d9
+    if (virJSONValueObjectGetNumberUlong(ret, "setup-time",
9119d9
+                                         &status->setup_time) == 0)
9119d9
+        status->setup_time_set = true;
9119d9
+
9119d9
     if (status->status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE ||
9119d9
         status->status == QEMU_MONITOR_MIGRATION_STATUS_COMPLETED) {
9119d9
         virJSONValuePtr ram = virJSONValueObjectGet(ret, "ram");
9119d9
@@ -2506,6 +2511,12 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
9119d9
             return -1;
9119d9
         }
9119d9
 
9119d9
+        if (virJSONValueObjectGetNumberDouble(ram, "mbps", &mbps) == 0 &&
9119d9
+            mbps > 0) {
9119d9
+            /* mpbs from QEMU reports Mbits/s (M as in 10^6 not Mi as 2^20) */
9119d9
+            status->ram_bps = mbps * (1000 * 1000 / 8);
9119d9
+        }
9119d9
+
9119d9
         if (virJSONValueObjectGetNumberUlong(ram, "duplicate",
9119d9
                                              &status->ram_duplicate) == 0)
9119d9
             status->ram_duplicate_set = true;
9119d9
@@ -2542,6 +2553,12 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
9119d9
                                  "data was missing"));
9119d9
                 return -1;
9119d9
             }
9119d9
+
9119d9
+            if (virJSONValueObjectGetNumberDouble(disk, "mbps", &mbps) == 0 &&
9119d9
+                mbps > 0) {
9119d9
+                /* mpbs from QEMU reports Mbits/s (M as in 10^6 not Mi as 2^20) */
9119d9
+                status->disk_bps = mbps * (1000 * 1000 / 8);
9119d9
+            }
9119d9
         }
9119d9
 
9119d9
         virJSONValuePtr comp = virJSONValueObjectGet(ret, "xbzrle-cache");
9119d9
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
9119d9
index f964856..683d92e 100644
9119d9
--- a/tools/virsh-domain.c
9119d9
+++ b/tools/virsh-domain.c
9119d9
@@ -5309,6 +5309,16 @@ cmdDomjobinfo(vshControl *ctl, const vshCmd *cmd)
9119d9
         vshPrint(ctl, "%-17s %-.3lf %s\n", _("Memory remaining:"), val, unit);
9119d9
         val = vshPrettyCapacity(info.memTotal, &unit);
9119d9
         vshPrint(ctl, "%-17s %-.3lf %s\n", _("Memory total:"), val, unit);
9119d9
+
9119d9
+        if ((rc = virTypedParamsGetULLong(params, nparams,
9119d9
+                                          VIR_DOMAIN_JOB_MEMORY_BPS,
9119d9
+                                          &value)) < 0) {
9119d9
+            goto save_error;
9119d9
+        } else if (rc && value) {
9119d9
+            val = vshPrettyCapacity(value, &unit);
9119d9
+            vshPrint(ctl, "%-17s %-.3lf %s/s\n",
9119d9
+                     _("Memory bandwidth:"), val, unit);
9119d9
+        }
9119d9
     }
9119d9
 
9119d9
     if (info.fileTotal || info.fileRemaining || info.fileProcessed) {
9119d9
@@ -5318,6 +5328,16 @@ cmdDomjobinfo(vshControl *ctl, const vshCmd *cmd)
9119d9
         vshPrint(ctl, "%-17s %-.3lf %s\n", _("File remaining:"), val, unit);
9119d9
         val = vshPrettyCapacity(info.fileTotal, &unit);
9119d9
         vshPrint(ctl, "%-17s %-.3lf %s\n", _("File total:"), val, unit);
9119d9
+
9119d9
+        if ((rc = virTypedParamsGetULLong(params, nparams,
9119d9
+                                          VIR_DOMAIN_JOB_DISK_BPS,
9119d9
+                                          &value)) < 0) {
9119d9
+            goto save_error;
9119d9
+        } else if (rc && value) {
9119d9
+            val = vshPrettyCapacity(value, &unit);
9119d9
+            vshPrint(ctl, "%-17s %-.3lf %s/s\n",
9119d9
+                     _("File bandwidth:"), val, unit);
9119d9
+        }
9119d9
     }
9119d9
 
9119d9
     if ((rc = virTypedParamsGetULLong(params, nparams,
9119d9
@@ -5358,6 +5378,13 @@ cmdDomjobinfo(vshControl *ctl, const vshCmd *cmd)
9119d9
     }
9119d9
 
9119d9
     if ((rc = virTypedParamsGetULLong(params, nparams,
9119d9
+                                      VIR_DOMAIN_JOB_SETUP_TIME,
9119d9
+                                      &value)) < 0)
9119d9
+        goto save_error;
9119d9
+    else if (rc)
9119d9
+        vshPrint(ctl, "%-17s %-12llu ms\n", _("Setup time:"), value);
9119d9
+
9119d9
+    if ((rc = virTypedParamsGetULLong(params, nparams,
9119d9
                                       VIR_DOMAIN_JOB_COMPRESSION_CACHE,
9119d9
                                       &value)) < 0) {
9119d9
         goto save_error;
9119d9
-- 
9119d9
2.1.1
9119d9