render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
9119d9
From b03557531795877c47dd9b0aaa6f4fb0c154c87a Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <b03557531795877c47dd9b0aaa6f4fb0c154c87a@dist-git>
9119d9
From: Jiri Denemark <jdenemar@redhat.com>
9119d9
Date: Thu, 28 Aug 2014 14:06:10 +0200
9119d9
Subject: [PATCH] qemu: Transfer migration statistics to destination
9119d9
9119d9
When migrating a transient domain or with VIR_MIGRATE_UNDEFINE_SOURCE
9119d9
flag, the domain may disappear from source host. And so will migration
9119d9
statistics associated with the domain. We need to transfer the
9119d9
statistics at the end of a migration so that they can be queried at the
9119d9
destination host.
9119d9
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
(cherry picked from commit 5d6fb96338bb8fcb687e22afda2cd7db16b01165)
9119d9
9119d9
https://bugzilla.redhat.com/show_bug.cgi?id=1063724
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
---
9119d9
 src/qemu/qemu_migration.c | 190 +++++++++++++++++++++++++++++++++++++++++++++-
9119d9
 1 file changed, 187 insertions(+), 3 deletions(-)
9119d9
9119d9
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
9119d9
index ba3ca66..9b1e94b 100644
9119d9
--- a/src/qemu/qemu_migration.c
9119d9
+++ b/src/qemu/qemu_migration.c
9119d9
@@ -80,6 +80,7 @@ enum qemuMigrationCookieFlags {
9119d9
     QEMU_MIGRATION_COOKIE_FLAG_PERSISTENT,
9119d9
     QEMU_MIGRATION_COOKIE_FLAG_NETWORK,
9119d9
     QEMU_MIGRATION_COOKIE_FLAG_NBD,
9119d9
+    QEMU_MIGRATION_COOKIE_FLAG_STATS,
9119d9
 
9119d9
     QEMU_MIGRATION_COOKIE_FLAG_LAST
9119d9
 };
9119d9
@@ -91,7 +92,8 @@ VIR_ENUM_IMPL(qemuMigrationCookieFlag,
9119d9
               "lockstate",
9119d9
               "persistent",
9119d9
               "network",
9119d9
-              "nbd");
9119d9
+              "nbd",
9119d9
+              "statistics");
9119d9
 
9119d9
 enum qemuMigrationCookieFeatures {
9119d9
     QEMU_MIGRATION_COOKIE_GRAPHICS  = (1 << QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS),
9119d9
@@ -99,6 +101,7 @@ enum qemuMigrationCookieFeatures {
9119d9
     QEMU_MIGRATION_COOKIE_PERSISTENT = (1 << QEMU_MIGRATION_COOKIE_FLAG_PERSISTENT),
9119d9
     QEMU_MIGRATION_COOKIE_NETWORK = (1 << QEMU_MIGRATION_COOKIE_FLAG_NETWORK),
9119d9
     QEMU_MIGRATION_COOKIE_NBD = (1 << QEMU_MIGRATION_COOKIE_FLAG_NBD),
9119d9
+    QEMU_MIGRATION_COOKIE_STATS = (1 << QEMU_MIGRATION_COOKIE_FLAG_STATS),
9119d9
 };
9119d9
 
9119d9
 typedef struct _qemuMigrationCookieGraphics qemuMigrationCookieGraphics;
9119d9
@@ -169,6 +172,9 @@ struct _qemuMigrationCookie {
9119d9
 
9119d9
     /* If (flags & QEMU_MIGRATION_COOKIE_NBD) */
9119d9
     qemuMigrationCookieNBDPtr nbd;
9119d9
+
9119d9
+    /* If (flags & QEMU_MIGRATION_COOKIE_STATS) */
9119d9
+    qemuDomainJobInfoPtr jobInfo;
9119d9
 };
9119d9
 
9119d9
 static void qemuMigrationCookieGraphicsFree(qemuMigrationCookieGraphicsPtr grap)
9119d9
@@ -533,6 +539,25 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
9119d9
 }
9119d9
 
9119d9
 
9119d9
+static int
9119d9
+qemuMigrationCookieAddStatistics(qemuMigrationCookiePtr mig,
9119d9
+                                 virDomainObjPtr vm)
9119d9
+{
9119d9
+    qemuDomainObjPrivatePtr priv = vm->privateData;
9119d9
+
9119d9
+    if (!priv->job.completed)
9119d9
+        return 0;
9119d9
+
9119d9
+    if (!mig->jobInfo && VIR_ALLOC(mig->jobInfo) < 0)
9119d9
+        return -1;
9119d9
+
9119d9
+    *mig->jobInfo = *priv->job.completed;
9119d9
+    mig->flags |= QEMU_MIGRATION_COOKIE_STATS;
9119d9
+
9119d9
+    return 0;
9119d9
+}
9119d9
+
9119d9
+
9119d9
 static void qemuMigrationCookieGraphicsXMLFormat(virBufferPtr buf,
9119d9
                                                  qemuMigrationCookieGraphicsPtr grap)
9119d9
 {
9119d9
@@ -589,6 +614,81 @@ qemuMigrationCookieNetworkXMLFormat(virBufferPtr buf,
9119d9
 }
9119d9
 
9119d9
 
9119d9
+static void
9119d9
+qemuMigrationCookieStatisticsXMLFormat(virBufferPtr buf,
9119d9
+                                       qemuDomainJobInfoPtr jobInfo)
9119d9
+{
9119d9
+    qemuMonitorMigrationStatus *status = &jobInfo->status;
9119d9
+
9119d9
+    virBufferAddLit(buf, "<statistics>\n");
9119d9
+    virBufferAdjustIndent(buf, 2);
9119d9
+
9119d9
+    virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                      VIR_DOMAIN_JOB_TIME_ELAPSED,
9119d9
+                      jobInfo->timeElapsed);
9119d9
+    virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                      VIR_DOMAIN_JOB_TIME_REMAINING,
9119d9
+                      jobInfo->timeRemaining);
9119d9
+    if (status->downtime_set)
9119d9
+        virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                          VIR_DOMAIN_JOB_DOWNTIME,
9119d9
+                          status->downtime);
9119d9
+
9119d9
+    virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                      VIR_DOMAIN_JOB_MEMORY_TOTAL,
9119d9
+                      status->ram_total);
9119d9
+    virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                      VIR_DOMAIN_JOB_MEMORY_PROCESSED,
9119d9
+                      status->ram_transferred);
9119d9
+    virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                      VIR_DOMAIN_JOB_MEMORY_REMAINING,
9119d9
+                      status->ram_remaining);
9119d9
+
9119d9
+    if (status->ram_duplicate_set) {
9119d9
+        virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                          VIR_DOMAIN_JOB_MEMORY_CONSTANT,
9119d9
+                          status->ram_duplicate);
9119d9
+        virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                          VIR_DOMAIN_JOB_MEMORY_NORMAL,
9119d9
+                          status->ram_normal);
9119d9
+        virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                          VIR_DOMAIN_JOB_MEMORY_NORMAL_BYTES,
9119d9
+                          status->ram_normal_bytes);
9119d9
+    }
9119d9
+
9119d9
+    virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                      VIR_DOMAIN_JOB_DISK_TOTAL,
9119d9
+                      status->disk_total);
9119d9
+    virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                      VIR_DOMAIN_JOB_DISK_PROCESSED,
9119d9
+                      status->disk_transferred);
9119d9
+    virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                      VIR_DOMAIN_JOB_DISK_REMAINING,
9119d9
+                      status->disk_remaining);
9119d9
+
9119d9
+    if (status->xbzrle_set) {
9119d9
+        virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                          VIR_DOMAIN_JOB_COMPRESSION_CACHE,
9119d9
+                          status->xbzrle_cache_size);
9119d9
+        virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                          VIR_DOMAIN_JOB_COMPRESSION_BYTES,
9119d9
+                          status->xbzrle_bytes);
9119d9
+        virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                          VIR_DOMAIN_JOB_COMPRESSION_PAGES,
9119d9
+                          status->xbzrle_pages);
9119d9
+        virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                          VIR_DOMAIN_JOB_COMPRESSION_CACHE_MISSES,
9119d9
+                          status->xbzrle_cache_miss);
9119d9
+        virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
+                          VIR_DOMAIN_JOB_COMPRESSION_OVERFLOW,
9119d9
+                          status->xbzrle_overflow);
9119d9
+    }
9119d9
+
9119d9
+    virBufferAdjustIndent(buf, -2);
9119d9
+    virBufferAddLit(buf, "</statistics>\n");
9119d9
+}
9119d9
+
9119d9
+
9119d9
 static int
9119d9
 qemuMigrationCookieXMLFormat(virQEMUDriverPtr driver,
9119d9
                              virBufferPtr buf,
9119d9
@@ -650,6 +750,9 @@ qemuMigrationCookieXMLFormat(virQEMUDriverPtr driver,
9119d9
         virBufferAddLit(buf, "/>\n");
9119d9
     }
9119d9
 
9119d9
+    if (mig->flags & QEMU_MIGRATION_COOKIE_STATS && mig->jobInfo)
9119d9
+        qemuMigrationCookieStatisticsXMLFormat(buf, mig->jobInfo);
9119d9
+
9119d9
     virBufferAdjustIndent(buf, -2);
9119d9
     virBufferAddLit(buf, "</qemu-migration>\n");
9119d9
     return 0;
9119d9
@@ -772,6 +875,70 @@ qemuMigrationCookieNetworkXMLParse(xmlXPathContextPtr ctxt)
9119d9
 }
9119d9
 
9119d9
 
9119d9
+static qemuDomainJobInfoPtr
9119d9
+qemuMigrationCookieStatisticsXMLParse(xmlXPathContextPtr ctxt)
9119d9
+{
9119d9
+    qemuDomainJobInfoPtr jobInfo = NULL;
9119d9
+    qemuMonitorMigrationStatus *status;
9119d9
+    xmlNodePtr save_ctxt = ctxt->node;
9119d9
+
9119d9
+    if (!(ctxt->node = virXPathNode("./statistics", ctxt)))
9119d9
+        goto cleanup;
9119d9
+
9119d9
+    if (VIR_ALLOC(jobInfo) < 0)
9119d9
+        goto cleanup;
9119d9
+
9119d9
+    status = &jobInfo->status;
9119d9
+    jobInfo->type = VIR_DOMAIN_JOB_COMPLETED;
9119d9
+
9119d9
+    virXPathULongLong("string(./" VIR_DOMAIN_JOB_TIME_ELAPSED "[1])",
9119d9
+                      ctxt, &jobInfo->timeElapsed);
9119d9
+    virXPathULongLong("string(./" VIR_DOMAIN_JOB_TIME_REMAINING "[1])",
9119d9
+                      ctxt, &jobInfo->timeRemaining);
9119d9
+    if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_DOWNTIME "[1])",
9119d9
+                          ctxt, &status->downtime) == 0)
9119d9
+        status->downtime_set = true;
9119d9
+
9119d9
+    virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_TOTAL "[1])",
9119d9
+                      ctxt, &status->ram_total);
9119d9
+    virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_PROCESSED "[1])",
9119d9
+                      ctxt, &status->ram_transferred);
9119d9
+    virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_REMAINING "[1])",
9119d9
+                      ctxt, &status->ram_remaining);
9119d9
+
9119d9
+    if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_CONSTANT "[1])",
9119d9
+                          ctxt, &status->ram_duplicate) == 0)
9119d9
+        status->ram_duplicate_set = true;
9119d9
+    virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_NORMAL "[1])",
9119d9
+                      ctxt, &status->ram_normal);
9119d9
+    virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_NORMAL_BYTES "[1])",
9119d9
+                      ctxt, &status->ram_normal_bytes);
9119d9
+
9119d9
+    virXPathULongLong("string(./" VIR_DOMAIN_JOB_DISK_TOTAL "[1])",
9119d9
+                      ctxt, &status->disk_total);
9119d9
+    virXPathULongLong("string(./" VIR_DOMAIN_JOB_DISK_PROCESSED "[1])",
9119d9
+                      ctxt, &status->disk_transferred);
9119d9
+    virXPathULongLong("string(./" VIR_DOMAIN_JOB_DISK_REMAINING "[1])",
9119d9
+                      ctxt, &status->disk_remaining);
9119d9
+
9119d9
+    if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_COMPRESSION_CACHE "[1])",
9119d9
+                          ctxt, &status->xbzrle_cache_size) == 0)
9119d9
+        status->xbzrle_set = true;
9119d9
+    virXPathULongLong("string(./" VIR_DOMAIN_JOB_COMPRESSION_BYTES "[1])",
9119d9
+                      ctxt, &status->xbzrle_bytes);
9119d9
+    virXPathULongLong("string(./" VIR_DOMAIN_JOB_COMPRESSION_PAGES "[1])",
9119d9
+                      ctxt, &status->xbzrle_pages);
9119d9
+    virXPathULongLong("string(./" VIR_DOMAIN_JOB_COMPRESSION_CACHE_MISSES "[1])",
9119d9
+                      ctxt, &status->xbzrle_cache_miss);
9119d9
+    virXPathULongLong("string(./" VIR_DOMAIN_JOB_COMPRESSION_OVERFLOW "[1])",
9119d9
+                      ctxt, &status->xbzrle_overflow);
9119d9
+
9119d9
+ cleanup:
9119d9
+    ctxt->node = save_ctxt;
9119d9
+    return jobInfo;
9119d9
+}
9119d9
+
9119d9
+
9119d9
 static int
9119d9
 qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
9119d9
                             virQEMUDriverPtr driver,
9119d9
@@ -947,6 +1114,11 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
9119d9
         VIR_FREE(port);
9119d9
     }
9119d9
 
9119d9
+    if (flags & QEMU_MIGRATION_COOKIE_STATS &&
9119d9
+        virXPathBoolean("boolean(./statistics)", ctxt) &&
9119d9
+        (!(mig->jobInfo = qemuMigrationCookieStatisticsXMLParse(ctxt))))
9119d9
+        goto error;
9119d9
+
9119d9
     virObjectUnref(caps);
9119d9
     return 0;
9119d9
 
9119d9
@@ -1017,6 +1189,10 @@ qemuMigrationBakeCookie(qemuMigrationCookiePtr mig,
9119d9
         qemuMigrationCookieAddNBD(mig, driver, dom) < 0)
9119d9
         return -1;
9119d9
 
9119d9
+    if (flags & QEMU_MIGRATION_COOKIE_STATS &&
9119d9
+        qemuMigrationCookieAddStatistics(mig, dom) < 0)
9119d9
+        return -1;
9119d9
+
9119d9
     if (!(*cookieout = qemuMigrationCookieXMLFormatStr(driver, mig)))
9119d9
         return -1;
9119d9
 
9119d9
@@ -3424,7 +3600,8 @@ qemuMigrationRun(virQEMUDriverPtr driver,
9119d9
     if (priv->job.completed)
9119d9
         qemuDomainJobInfoUpdateTime(priv->job.completed);
9119d9
 
9119d9
-    cookieFlags |= QEMU_MIGRATION_COOKIE_NETWORK;
9119d9
+    cookieFlags |= QEMU_MIGRATION_COOKIE_NETWORK |
9119d9
+                   QEMU_MIGRATION_COOKIE_STATS;
9119d9
     if (flags & VIR_MIGRATE_PERSIST_DEST)
9119d9
         cookieFlags |= QEMU_MIGRATION_COOKIE_PERSISTENT;
9119d9
     if (ret == 0 &&
9119d9
@@ -4508,8 +4685,10 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
9119d9
                                        : QEMU_MIGRATION_PHASE_FINISH2);
9119d9
 
9119d9
     qemuDomainCleanupRemove(vm, qemuMigrationPrepareCleanup);
9119d9
+    VIR_FREE(priv->job.completed);
9119d9
 
9119d9
-    cookie_flags = QEMU_MIGRATION_COOKIE_NETWORK;
9119d9
+    cookie_flags = QEMU_MIGRATION_COOKIE_NETWORK |
9119d9
+                   QEMU_MIGRATION_COOKIE_STATS;
9119d9
     if (flags & VIR_MIGRATE_PERSIST_DEST)
9119d9
         cookie_flags |= QEMU_MIGRATION_COOKIE_PERSISTENT;
9119d9
 
9119d9
@@ -4527,6 +4706,11 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
9119d9
             goto endjob;
9119d9
         }
9119d9
 
9119d9
+        if (mig->jobInfo) {
9119d9
+            priv->job.completed = mig->jobInfo;
9119d9
+            mig->jobInfo = NULL;
9119d9
+        }
9119d9
+
9119d9
         if (!(flags & VIR_MIGRATE_OFFLINE)) {
9119d9
             if (qemuMigrationVPAssociatePortProfiles(vm->def) < 0) {
9119d9
                 qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED,
9119d9
-- 
9119d9
2.1.0
9119d9