From d38fa8e57331b666839b6d9cc3744058f8de8093 Mon Sep 17 00:00:00 2001
From: Hao Wang <wanghao232@huawei.com>
Date: Tue, 16 Mar 2021 20:32:50 +0800
Subject: [PATCH 6/7] migration/dirtyrate: Extend dirtyrate statistics for
 domGetStats
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Extend dirtyrate statistics for domGetStats to display the information
of a domain's memory dirty rate produced by domainStartDirtyRateCalc.

cherry-pick from fee42ea12044d1414c1a5c0b0dca30091f42e65d

Signed-off-by: Hao Wang <wanghao232@huawei.com>
Signed-off-by: Hyman Huang(黄勇) <huangy81@chinatelecom.cn>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
 include/libvirt/libvirt-domain.h |  1 +
 src/libvirt-domain.c             | 15 ++++++++++
 src/qemu/qemu_driver.c           | 51 ++++++++++++++++++++++++++++++++
 3 files changed, 67 insertions(+)

diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 01dc64f4f4..e1954ae663 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -2167,6 +2167,7 @@ typedef enum {
     VIR_DOMAIN_STATS_PERF = (1 << 6), /* return domain perf event info */
     VIR_DOMAIN_STATS_IOTHREAD = (1 << 7), /* return iothread poll info */
     VIR_DOMAIN_STATS_MEMORY = (1 << 8), /* return domain memory info */
+    VIR_DOMAIN_STATS_DIRTYRATE = (1 << 9), /* return domain dirty rate info */
 } virDomainStatsTypes;
 
 typedef enum {
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 974a5a5f36..6a37ea85b7 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11683,6 +11683,21 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
  *                       bytes consumed by @vcpus that passing through all
  *                       memory controllers, either local or remote controller.
  *
+ * VIR_DOMAIN_STATS_DIRTYRATE:
+ *     Return memory dirty rate information. The typed parameter keys are in
+ *     this format:
+ *
+ *     "dirtyrate.calc_status" - the status of last memory dirty rate calculation,
+ *                               returned as int from virDomainDirtyRateStatus
+ *                               enum.
+ *     "dirtyrate.calc_start_time" - the start time of last memory dirty rate
+ *                                   calculation as long long.
+ *     "dirtyrate.calc_period" - the period of last memory dirty rate calculation
+ *                               as int.
+ *     "dirtyrate.megabytes_per_second" - the calculated memory dirty rate in
+ *                                        MiB/s as long long. It is produced
+ *                                        only if the calc_status is measured.
+ *
  * Note that entire stats groups or individual stat fields may be missing from
  * the output in case they are not supported by the given hypervisor, are not
  * applicable for the current state of the guest domain, or their retrieval
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b0a4905279..5e9af6399d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -21734,6 +21734,56 @@ qemuDomainGetStatsPerf(virQEMUDriverPtr driver G_GNUC_UNUSED,
     return 0;
 }
 
+static int
+qemuDomainGetStatsDirtyRateMon(virQEMUDriverPtr driver,
+                               virDomainObjPtr vm,
+                               qemuMonitorDirtyRateInfoPtr info)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    int ret;
+
+    qemuDomainObjEnterMonitor(driver, vm);
+    ret = qemuMonitorQueryDirtyRate(priv->mon, info);
+    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        ret = -1;
+
+    return ret;
+}
+
+static int
+qemuDomainGetStatsDirtyRate(virQEMUDriverPtr driver,
+                           virDomainObjPtr dom,
+                           virTypedParamListPtr params,
+                           unsigned int privflags)
+{
+    qemuMonitorDirtyRateInfo info;
+
+    if (!HAVE_JOB(privflags) || !virDomainObjIsActive(dom))
+        return 0;
+
+    if (qemuDomainGetStatsDirtyRateMon(driver, dom, &info) < 0)
+        return -1;
+
+    if (virTypedParamListAddInt(params, info.status,
+                                "dirtyrate.calc_status") < 0)
+        return -1;
+
+    if (virTypedParamListAddLLong(params, info.startTime,
+                                  "dirtyrate.calc_start_time") < 0)
+        return -1;
+
+    if (virTypedParamListAddInt(params, info.calcTime,
+                                "dirtyrate.calc_period") < 0)
+        return -1;
+
+    if ((info.status == VIR_DOMAIN_DIRTYRATE_MEASURED) &&
+        virTypedParamListAddLLong(params, info.dirtyRate,
+                                  "dirtyrate.megabytes_per_second") < 0)
+        return -1;
+
+    return 0;
+}
+
 typedef int
 (*qemuDomainGetStatsFunc)(virQEMUDriverPtr driver,
                           virDomainObjPtr dom,
@@ -21756,6 +21806,7 @@ static struct qemuDomainGetStatsWorker qemuDomainGetStatsWorkers[] = {
     { qemuDomainGetStatsPerf, VIR_DOMAIN_STATS_PERF, false },
     { qemuDomainGetStatsIOThread, VIR_DOMAIN_STATS_IOTHREAD, true },
     { qemuDomainGetStatsMemory, VIR_DOMAIN_STATS_MEMORY, false },
+    { qemuDomainGetStatsDirtyRate, VIR_DOMAIN_STATS_DIRTYRATE, true },
     { NULL, 0, false }
 };
 
-- 
2.27.0

