|
|
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 |
|