render / rpms / libvirt

Forked from rpms/libvirt 11 months ago
Clone
9119d9
From b03082de96085cbca052d979ce1679ca65ab1ede Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <b03082de96085cbca052d979ce1679ca65ab1ede@dist-git>
9119d9
From: Jiri Denemark <jdenemar@redhat.com>
9119d9
Date: Thu, 28 Aug 2014 16:37:38 +0200
9119d9
Subject: [PATCH] qemu: Recompute downtime and total time when migration
9119d9
 completes
9119d9
9119d9
Total time of a migration and total downtime transfered from a source to
9119d9
a destination host do not count with the transfer time to the
9119d9
destination host and with the time elapsed before guest CPUs are
9119d9
resumed. Thus, source libvirtd remembers when migration started and when
9119d9
guest CPUs were paused. Both timestamps are transferred to destination
9119d9
libvirtd which uses them to compute total migration time and total
9119d9
downtime. Obviously, this requires the time to be synchronized between
9119d9
the two hosts. The reported times are useless otherwise but they would
9119d9
be equally useless if we didn't do this recomputation so don't lose
9119d9
anything by doing it.
9119d9
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
(cherry picked from commit eaee338ae67e29fd93276563238633eae1097c82)
9119d9
9119d9
https://bugzilla.redhat.com/show_bug.cgi?id=1063724
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
---
9119d9
 src/libvirt.c             |  5 ++++-
9119d9
 src/qemu/qemu_domain.c    | 28 ++++++++++++++++++++++++++++
9119d9
 src/qemu/qemu_domain.h    |  3 +++
9119d9
 src/qemu/qemu_migration.c | 15 ++++++++++++++-
9119d9
 src/qemu/qemu_process.c   |  9 ++++++++-
9119d9
 tools/virsh.pod           |  5 ++++-
9119d9
 6 files changed, 61 insertions(+), 4 deletions(-)
9119d9
9119d9
diff --git a/src/libvirt.c b/src/libvirt.c
9119d9
index 6fa0a6b..61d0543 100644
9119d9
--- a/src/libvirt.c
9119d9
+++ b/src/libvirt.c
9119d9
@@ -17581,7 +17581,10 @@ virDomainGetJobInfo(virDomainPtr domain, virDomainJobInfoPtr info)
9119d9
  * return statistics about a recently completed job. Specifically, this
9119d9
  * flag may be used to query statistics of a completed incoming migration.
9119d9
  * Statistics of a completed job are automatically destroyed once read or
9119d9
- * when libvirtd is restarted.
9119d9
+ * when libvirtd is restarted. Note that time information returned for
9119d9
+ * completed migrations may be completely irrelevant unless both source and
9119d9
+ * destination hosts have synchronized time (i.e., NTP daemon is running on
9119d9
+ * both of them).
9119d9
  *
9119d9
  * Returns 0 in case of success and -1 in case of failure.
9119d9
  */
9119d9
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
9119d9
index 78d6e8c..c0306d7 100644
9119d9
--- a/src/qemu/qemu_domain.c
9119d9
+++ b/src/qemu/qemu_domain.c
9119d9
@@ -222,11 +222,39 @@ qemuDomainJobInfoUpdateTime(qemuDomainJobInfoPtr jobInfo)
9119d9
     if (virTimeMillisNow(&now) < 0)
9119d9
         return -1;
9119d9
 
9119d9
+    if (now < jobInfo->started) {
9119d9
+        VIR_WARN("Async job starts in the future");
9119d9
+        jobInfo->started = 0;
9119d9
+        return 0;
9119d9
+    }
9119d9
+
9119d9
     jobInfo->timeElapsed = now - jobInfo->started;
9119d9
     return 0;
9119d9
 }
9119d9
 
9119d9
 int
9119d9
+qemuDomainJobInfoUpdateDowntime(qemuDomainJobInfoPtr jobInfo)
9119d9
+{
9119d9
+    unsigned long long now;
9119d9
+
9119d9
+    if (!jobInfo->stopped)
9119d9
+        return 0;
9119d9
+
9119d9
+    if (virTimeMillisNow(&now) < 0)
9119d9
+        return -1;
9119d9
+
9119d9
+    if (now < jobInfo->stopped) {
9119d9
+        VIR_WARN("Guest's CPUs stopped in the future");
9119d9
+        jobInfo->stopped = 0;
9119d9
+        return 0;
9119d9
+    }
9119d9
+
9119d9
+    jobInfo->status.downtime = now - jobInfo->stopped;
9119d9
+    jobInfo->status.downtime_set = true;
9119d9
+    return 0;
9119d9
+}
9119d9
+
9119d9
+int
9119d9
 qemuDomainJobInfoToInfo(qemuDomainJobInfoPtr jobInfo,
9119d9
                         virDomainJobInfoPtr info)
9119d9
 {
9119d9
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
9119d9
index 2e16cde..479b51f 100644
9119d9
--- a/src/qemu/qemu_domain.h
9119d9
+++ b/src/qemu/qemu_domain.h
9119d9
@@ -105,6 +105,7 @@ typedef qemuDomainJobInfo *qemuDomainJobInfoPtr;
9119d9
 struct _qemuDomainJobInfo {
9119d9
     virDomainJobType type;
9119d9
     unsigned long long started; /* When the async job started */
9119d9
+    unsigned long long stopped; /* When the domain's CPUs were stopped */
9119d9
     /* Computed values */
9119d9
     unsigned long long timeElapsed;
9119d9
     unsigned long long timeRemaining;
9119d9
@@ -391,6 +392,8 @@ bool qemuDomainAgentAvailable(qemuDomainObjPrivatePtr priv,
9119d9
 
9119d9
 int qemuDomainJobInfoUpdateTime(qemuDomainJobInfoPtr jobInfo)
9119d9
     ATTRIBUTE_NONNULL(1);
9119d9
+int qemuDomainJobInfoUpdateDowntime(qemuDomainJobInfoPtr jobInfo)
9119d9
+    ATTRIBUTE_NONNULL(1);
9119d9
 int qemuDomainJobInfoToInfo(qemuDomainJobInfoPtr jobInfo,
9119d9
                             virDomainJobInfoPtr info)
9119d9
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
9119d9
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
9119d9
index 9b1e94b..c7a41b1 100644
9119d9
--- a/src/qemu/qemu_migration.c
9119d9
+++ b/src/qemu/qemu_migration.c
9119d9
@@ -623,6 +623,9 @@ qemuMigrationCookieStatisticsXMLFormat(virBufferPtr buf,
9119d9
     virBufferAddLit(buf, "<statistics>\n");
9119d9
     virBufferAdjustIndent(buf, 2);
9119d9
 
9119d9
+    virBufferAsprintf(buf, "<started>%llu</started>\n", jobInfo->started);
9119d9
+    virBufferAsprintf(buf, "<stopped>%llu</stopped>\n", jobInfo->stopped);
9119d9
+
9119d9
     virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
9119d9
                       VIR_DOMAIN_JOB_TIME_ELAPSED,
9119d9
                       jobInfo->timeElapsed);
9119d9
@@ -891,6 +894,9 @@ qemuMigrationCookieStatisticsXMLParse(xmlXPathContextPtr ctxt)
9119d9
     status = &jobInfo->status;
9119d9
     jobInfo->type = VIR_DOMAIN_JOB_COMPLETED;
9119d9
 
9119d9
+    virXPathULongLong("string(./started[1])", ctxt, &jobInfo->started);
9119d9
+    virXPathULongLong("string(./stopped[1])", ctxt, &jobInfo->stopped);
9119d9
+
9119d9
     virXPathULongLong("string(./" VIR_DOMAIN_JOB_TIME_ELAPSED "[1])",
9119d9
                       ctxt, &jobInfo->timeElapsed);
9119d9
     virXPathULongLong("string(./" VIR_DOMAIN_JOB_TIME_REMAINING "[1])",
9119d9
@@ -2015,6 +2021,7 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver,
9119d9
     }
9119d9
 
9119d9
     if (jobInfo->type == VIR_DOMAIN_JOB_COMPLETED) {
9119d9
+        qemuDomainJobInfoUpdateDowntime(jobInfo);
9119d9
         VIR_FREE(priv->job.completed);
9119d9
         if (VIR_ALLOC(priv->job.completed) == 0)
9119d9
             *priv->job.completed = *jobInfo;
9119d9
@@ -3597,8 +3604,10 @@ qemuMigrationRun(virQEMUDriverPtr driver,
9119d9
         VIR_FORCE_CLOSE(fd);
9119d9
     }
9119d9
 
9119d9
-    if (priv->job.completed)
9119d9
+    if (priv->job.completed) {
9119d9
         qemuDomainJobInfoUpdateTime(priv->job.completed);
9119d9
+        qemuDomainJobInfoUpdateDowntime(priv->job.completed);
9119d9
+    }
9119d9
 
9119d9
     cookieFlags |= QEMU_MIGRATION_COOKIE_NETWORK |
9119d9
                    QEMU_MIGRATION_COOKIE_STATS;
9119d9
@@ -4811,6 +4820,10 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
9119d9
                 }
9119d9
                 goto endjob;
9119d9
             }
9119d9
+            if (priv->job.completed) {
9119d9
+                qemuDomainJobInfoUpdateTime(priv->job.completed);
9119d9
+                qemuDomainJobInfoUpdateDowntime(priv->job.completed);
9119d9
+            }
9119d9
         }
9119d9
 
9119d9
         dom = virGetDomain(dconn, vm->def->name, vm->def->uuid);
9119d9
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
9119d9
index 9395af1..0f269b9 100644
9119d9
--- a/src/qemu/qemu_process.c
9119d9
+++ b/src/qemu/qemu_process.c
9119d9
@@ -754,6 +754,9 @@ qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
9119d9
         VIR_DEBUG("Transitioned guest %s to paused state",
9119d9
                   vm->def->name);
9119d9
 
9119d9
+        if (priv->job.current)
9119d9
+            ignore_value(virTimeMillisNow(&priv->job.current->stopped));
9119d9
+
9119d9
         virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_UNKNOWN);
9119d9
         event = virDomainEventLifecycleNewFromObj(vm,
9119d9
                                          VIR_DOMAIN_EVENT_SUSPENDED,
9119d9
@@ -2888,7 +2891,8 @@ qemuProcessStartCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm,
9119d9
 }
9119d9
 
9119d9
 
9119d9
-int qemuProcessStopCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm,
9119d9
+int qemuProcessStopCPUs(virQEMUDriverPtr driver,
9119d9
+                        virDomainObjPtr vm,
9119d9
                         virDomainPausedReason reason,
9119d9
                         qemuDomainAsyncJob asyncJob)
9119d9
 {
9119d9
@@ -2906,6 +2910,9 @@ int qemuProcessStopCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm,
9119d9
     if (ret < 0)
9119d9
         goto cleanup;
9119d9
 
9119d9
+    if (priv->job.current)
9119d9
+        ignore_value(virTimeMillisNow(&priv->job.current->stopped));
9119d9
+
9119d9
     virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, reason);
9119d9
     if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
9119d9
         VIR_WARN("Unable to release lease on %s", vm->def->name);
9119d9
diff --git a/tools/virsh.pod b/tools/virsh.pod
9119d9
index aad40d5..b28677f 100644
9119d9
--- a/tools/virsh.pod
9119d9
+++ b/tools/virsh.pod
9119d9
@@ -1117,7 +1117,10 @@ Abort the currently running domain job.
9119d9
 Returns information about jobs running on a domain. I<--completed> tells
9119d9
 virsh to return information about a recently finished job. Statistics of
9119d9
 a completed job are automatically destroyed once read or when libvirtd
9119d9
-is restarted.
9119d9
+is restarted. Note that time information returned for completed
9119d9
+migrations may be completely irrelevant unless both source and
9119d9
+destination hosts have synchronized time (i.e., NTP daemon is running
9119d9
+on both of them).
9119d9
 
9119d9
 =item B<domname> I<domain-id-or-uuid>
9119d9
 
9119d9
-- 
9119d9
2.1.0
9119d9