9119d9
From cad012440efa450ff92d4fdcccb99169f5b2deea Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <cad012440efa450ff92d4fdcccb99169f5b2deea@dist-git>
9119d9
From: Jiri Denemark <jdenemar@redhat.com>
9119d9
Date: Thu, 28 Aug 2014 13:52:58 +0200
9119d9
Subject: [PATCH] Add support for fetching statistics of completed jobs
9119d9
9119d9
virDomainGetJobStats gains new VIR_DOMAIN_JOB_STATS_COMPLETED flag that
9119d9
can be used to fetch statistics of a completed job rather than a
9119d9
currently running job.
9119d9
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
(cherry picked from commit 3a8688162e82a4004011f6f49f6a6fb3c2530f5f)
9119d9
9119d9
https://bugzilla.redhat.com/show_bug.cgi?id=1063724
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
---
9119d9
 include/libvirt/libvirt.h.in | 11 +++++++++++
9119d9
 src/libvirt.c                |  8 +++++++-
9119d9
 src/qemu/qemu_domain.c       |  1 +
9119d9
 src/qemu/qemu_domain.h       |  1 +
9119d9
 src/qemu/qemu_driver.c       | 25 +++++++++++++++++++------
9119d9
 src/qemu/qemu_migration.c    |  6 ++++++
9119d9
 src/qemu/qemu_monitor_json.c |  3 ++-
9119d9
 7 files changed, 47 insertions(+), 8 deletions(-)
9119d9
9119d9
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
9119d9
index a64f597..d895560 100644
9119d9
--- a/include/libvirt/libvirt.h.in
9119d9
+++ b/include/libvirt/libvirt.h.in
9119d9
@@ -4306,6 +4306,17 @@ struct _virDomainJobInfo {
9119d9
     unsigned long long fileRemaining;
9119d9
 };
9119d9
 
9119d9
+/**
9119d9
+ * virDomainGetJobStatsFlags:
9119d9
+ *
9119d9
+ * Flags OR'ed together to provide specific behavior when querying domain
9119d9
+ * job statistics.
9119d9
+ */
9119d9
+typedef enum {
9119d9
+    VIR_DOMAIN_JOB_STATS_COMPLETED = 1 << 0, /* return stats of a recently
9119d9
+                                              * completed job */
9119d9
+} virDomainGetJobStatsFlags;
9119d9
+
9119d9
 int virDomainGetJobInfo(virDomainPtr dom,
9119d9
                         virDomainJobInfoPtr info);
9119d9
 int virDomainGetJobStats(virDomainPtr domain,
9119d9
diff --git a/src/libvirt.c b/src/libvirt.c
9119d9
index 5d8f01c..6fa0a6b 100644
9119d9
--- a/src/libvirt.c
9119d9
+++ b/src/libvirt.c
9119d9
@@ -17567,7 +17567,7 @@ virDomainGetJobInfo(virDomainPtr domain, virDomainJobInfoPtr info)
9119d9
  * @type: where to store the job type (one of virDomainJobType)
9119d9
  * @params: where to store job statistics
9119d9
  * @nparams: number of items in @params
9119d9
- * @flags: extra flags; not used yet, so callers should always pass 0
9119d9
+ * @flags: bitwise-OR of virDomainGetJobStatsFlags
9119d9
  *
9119d9
  * Extract information about progress of a background job on a domain.
9119d9
  * Will return an error if the domain is not active. The function returns
9119d9
@@ -17577,6 +17577,12 @@ virDomainGetJobInfo(virDomainPtr domain, virDomainJobInfoPtr info)
9119d9
  * may receive fields that they do not understand in case they talk to a
9119d9
  * newer server.
9119d9
  *
9119d9
+ * When @flags contains VIR_DOMAIN_JOB_STATS_COMPLETED, the function will
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
+ *
9119d9
  * Returns 0 in case of success and -1 in case of failure.
9119d9
  */
9119d9
 int
9119d9
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
9119d9
index 8c94e27..78d6e8c 100644
9119d9
--- a/src/qemu/qemu_domain.c
9119d9
+++ b/src/qemu/qemu_domain.c
9119d9
@@ -199,6 +199,7 @@ static void
9119d9
 qemuDomainObjFreeJob(qemuDomainObjPrivatePtr priv)
9119d9
 {
9119d9
     VIR_FREE(priv->job.current);
9119d9
+    VIR_FREE(priv->job.completed);
9119d9
     virCondDestroy(&priv->job.cond);
9119d9
     virCondDestroy(&priv->job.asyncCond);
9119d9
 }
9119d9
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
9119d9
index 99c7d6a..2e16cde 100644
9119d9
--- a/src/qemu/qemu_domain.h
9119d9
+++ b/src/qemu/qemu_domain.h
9119d9
@@ -124,6 +124,7 @@ struct qemuDomainJobObj {
9119d9
     unsigned long long mask;            /* Jobs allowed during async job */
9119d9
     bool dump_memory_only;              /* use dump-guest-memory to do dump */
9119d9
     qemuDomainJobInfoPtr current;       /* async job progress data */
9119d9
+    qemuDomainJobInfoPtr completed;     /* statistics data of a recently completed job */
9119d9
     bool asyncAbort;                    /* abort of async job requested */
9119d9
 };
9119d9
 
9119d9
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
9119d9
index 6640a29..496fab5 100644
9119d9
--- a/src/qemu/qemu_driver.c
9119d9
+++ b/src/qemu/qemu_driver.c
9119d9
@@ -11659,9 +11659,10 @@ qemuDomainGetJobStats(virDomainPtr dom,
9119d9
 {
9119d9
     virDomainObjPtr vm;
9119d9
     qemuDomainObjPrivatePtr priv;
9119d9
+    qemuDomainJobInfoPtr jobInfo;
9119d9
     int ret = -1;
9119d9
 
9119d9
-    virCheckFlags(0, -1);
9119d9
+    virCheckFlags(VIR_DOMAIN_JOB_STATS_COMPLETED, -1);
9119d9
 
9119d9
     if (!(vm = qemuDomObjFromDomain(dom)))
9119d9
         goto cleanup;
9119d9
@@ -11671,13 +11672,19 @@ qemuDomainGetJobStats(virDomainPtr dom,
9119d9
     if (virDomainGetJobStatsEnsureACL(dom->conn, vm->def) < 0)
9119d9
         goto cleanup;
9119d9
 
9119d9
-    if (!virDomainObjIsActive(vm)) {
9119d9
+    if (!(flags & VIR_DOMAIN_JOB_STATS_COMPLETED) &&
9119d9
+        !virDomainObjIsActive(vm)) {
9119d9
         virReportError(VIR_ERR_OPERATION_INVALID,
9119d9
                        "%s", _("domain is not running"));
9119d9
         goto cleanup;
9119d9
     }
9119d9
 
9119d9
-    if (!priv->job.current) {
9119d9
+    if (flags & VIR_DOMAIN_JOB_STATS_COMPLETED)
9119d9
+        jobInfo = priv->job.completed;
9119d9
+    else
9119d9
+        jobInfo = priv->job.current;
9119d9
+
9119d9
+    if (!jobInfo) {
9119d9
         *type = VIR_DOMAIN_JOB_NONE;
9119d9
         *params = NULL;
9119d9
         *nparams = 0;
9119d9
@@ -11690,11 +11697,17 @@ qemuDomainGetJobStats(virDomainPtr dom,
9119d9
      * of incoming migration which we don't currently
9119d9
      * monitor actively in the background thread
9119d9
      */
9119d9
-    if (qemuDomainJobInfoUpdateTime(priv->job.current) < 0 ||
9119d9
-        qemuDomainJobInfoToParams(priv->job.current,
9119d9
-                                  type, params, nparams) < 0)
9119d9
+    if ((jobInfo->type == VIR_DOMAIN_JOB_BOUNDED ||
9119d9
+         jobInfo->type == VIR_DOMAIN_JOB_UNBOUNDED) &&
9119d9
+        qemuDomainJobInfoUpdateTime(jobInfo) < 0)
9119d9
         goto cleanup;
9119d9
 
9119d9
+    if (qemuDomainJobInfoToParams(jobInfo, type, params, nparams) < 0)
9119d9
+        goto cleanup;
9119d9
+
9119d9
+    if (flags & VIR_DOMAIN_JOB_STATS_COMPLETED)
9119d9
+        VIR_FREE(priv->job.completed);
9119d9
+
9119d9
     ret = 0;
9119d9
 
9119d9
  cleanup:
9119d9
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
9119d9
index 066cc97..ba3ca66 100644
9119d9
--- a/src/qemu/qemu_migration.c
9119d9
+++ b/src/qemu/qemu_migration.c
9119d9
@@ -1839,6 +1839,9 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver,
9119d9
     }
9119d9
 
9119d9
     if (jobInfo->type == VIR_DOMAIN_JOB_COMPLETED) {
9119d9
+        VIR_FREE(priv->job.completed);
9119d9
+        if (VIR_ALLOC(priv->job.completed) == 0)
9119d9
+            *priv->job.completed = *jobInfo;
9119d9
         return 0;
9119d9
     } else if (jobInfo->type == VIR_DOMAIN_JOB_UNBOUNDED) {
9119d9
         /* The migration was aborted by us rather than QEMU itself so let's
9119d9
@@ -3418,6 +3421,9 @@ qemuMigrationRun(virQEMUDriverPtr driver,
9119d9
         VIR_FORCE_CLOSE(fd);
9119d9
     }
9119d9
 
9119d9
+    if (priv->job.completed)
9119d9
+        qemuDomainJobInfoUpdateTime(priv->job.completed);
9119d9
+
9119d9
     cookieFlags |= QEMU_MIGRATION_COOKIE_NETWORK;
9119d9
     if (flags & VIR_MIGRATE_PERSIST_DEST)
9119d9
         cookieFlags |= QEMU_MIGRATION_COOKIE_PERSISTENT;
9119d9
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
9119d9
index cf26069..2ae8ee0 100644
9119d9
--- a/src/qemu/qemu_monitor_json.c
9119d9
+++ b/src/qemu/qemu_monitor_json.c
9119d9
@@ -2474,7 +2474,8 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
9119d9
     if (rc == 0)
9119d9
         status->downtime_set = true;
9119d9
 
9119d9
-    if (status->status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE) {
9119d9
+    if (status->status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE ||
9119d9
+        status->status == QEMU_MONITOR_MIGRATION_STATUS_COMPLETED) {
9119d9
         virJSONValuePtr ram = virJSONValueObjectGet(ret, "ram");
9119d9
         if (!ram) {
9119d9
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
9119d9
-- 
9119d9
2.1.0
9119d9