[PATCH v1 4/6] qemu_driver: Add mode option for qemuDomainStartDirtyRateCalc

huangy81 at chinatelecom.cn huangy81 at chinatelecom.cn
Thu Jan 27 03:36:20 UTC 2022


From: Hyman Huang(黄勇) <huangy81 at chinatelecom.cn>

Add mode option to extend qemuDomainStartDirtyRateCalc API,
which is introduced since qemu >= 6.2.

Signed-off-by: Hyman Huang(黄勇) <huangy81 at chinatelecom.cn>
---
 include/libvirt/libvirt-domain.h | 13 +++++++++++++
 src/qemu/qemu_driver.c           | 33 +++++++++++++++++++++++++++++++--
 src/qemu/qemu_monitor.c          |  5 +++--
 src/qemu/qemu_monitor.h          | 10 +++++++++-
 src/qemu/qemu_monitor_json.c     | 26 +++++++++++++++++++++-----
 src/qemu/qemu_monitor_json.h     |  3 ++-
 6 files changed, 79 insertions(+), 11 deletions(-)

diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 4da1a63..54bb23b 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -5257,6 +5257,19 @@ typedef enum {
 # endif
 } virDomainDirtyRateStatus;
 
+/**
+ * virDomainDirtyRateCalcFlags:
+ *
+ * Flags OR'ed together to provide specific behaviour when calculating dirty page
+ * rate for a Domain
+ *
+ */
+typedef enum {
+    VIR_DOMAIN_DIRTYRATE_MODE_PAGE_SAMPLING = 0,        /* default mode - page-sampling */
+    VIR_DOMAIN_DIRTYRATE_MODE_DIRTY_BITMAP = 1 << 0,    /* dirty-bitmap mode */
+    VIR_DOMAIN_DIRTYRATE_MODE_DIRTY_RING = 1 << 1,      /* dirty-ring mode */
+} virDomainDirtyRateCalcFlags;
+
 int virDomainStartDirtyRateCalc(virDomainPtr domain,
                                 int seconds,
                                 unsigned int flags);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0e8e9b1..feebfc4 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -20648,9 +20648,13 @@ qemuDomainStartDirtyRateCalc(virDomainPtr dom,
     virDomainObj *vm = NULL;
     qemuDomainObjPrivate *priv;
     g_autoptr(virQEMUCaps) qemucaps = NULL;
+    qemuMonitorDirtyRateCalcMode calcmode = VIR_DOMAIN_DIRTYRATE_CALC_MODE_PAGE_SAMPLING;
+    bool mode = false;
     int ret = -1;
 
-    virCheckFlags(0, -1);
+    virCheckFlags(VIR_DOMAIN_DIRTYRATE_MODE_PAGE_SAMPLING |
+                  VIR_DOMAIN_DIRTYRATE_MODE_DIRTY_BITMAP |
+                  VIR_DOMAIN_DIRTYRATE_MODE_DIRTY_RING, -1);
 
     if (!(qemucaps = virQEMUCapsCacheLookupDefault(driver->qemuCapsCache,
                                                    NULL, NULL, NULL, NULL,
@@ -20663,6 +20667,15 @@ qemuDomainStartDirtyRateCalc(virDomainPtr dom,
         return -1;
     }
 
+    mode = virQEMUCapsGet(qemucaps, QEMU_CAPS_DIRTYRATE_MODE);
+
+    if (!mode && (flags & VIR_DOMAIN_DIRTYRATE_MODE_DIRTY_BITMAP ||
+                 (flags & VIR_DOMAIN_DIRTYRATE_MODE_DIRTY_RING))) {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                       _("QEMU does not support calculating dirty page rate"
+                         "with specified mode"));
+    }
+
     if (seconds < MIN_DIRTYRATE_CALC_PERIOD ||
         seconds > MAX_DIRTYRATE_CALC_PERIOD) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -20676,6 +20689,22 @@ qemuDomainStartDirtyRateCalc(virDomainPtr dom,
     if (!(vm = qemuDomainObjFromDomain(dom)))
         return -1;
 
+    if (mode) {
+        /* libvirt-domain.c already guaranteed these two flags are exclusive.  */
+        if (flags & VIR_DOMAIN_DIRTYRATE_MODE_DIRTY_BITMAP) {
+            calcmode = VIR_DOMAIN_DIRTYRATE_CALC_MODE_DIRTY_BITMAP;
+        } else if (flags & VIR_DOMAIN_DIRTYRATE_MODE_DIRTY_RING) {
+            if (vm->def->features[VIR_DOMAIN_FEATURE_KVM] != VIR_TRISTATE_SWITCH_ON ||
+                vm->def->kvm_features->features[VIR_DOMAIN_KVM_DIRTY_RING] != VIR_TRISTATE_SWITCH_ON) {
+                virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                               _("Calculating dirty page rate with dirty-ring requires"
+                                 "dirty-ring feature enabled."));
+                goto cleanup;
+            }
+            calcmode = VIR_DOMAIN_DIRTYRATE_CALC_MODE_DIRTY_RING;
+        }
+    }
+
     if (virDomainStartDirtyRateCalcEnsureACL(dom->conn, vm->def) < 0)
         goto cleanup;
 
@@ -20692,7 +20721,7 @@ qemuDomainStartDirtyRateCalc(virDomainPtr dom,
 
     priv = vm->privateData;
     qemuDomainObjEnterMonitor(driver, vm);
-    ret = qemuMonitorStartDirtyRateCalc(priv->mon, seconds);
+    ret = qemuMonitorStartDirtyRateCalc(priv->mon, seconds, calcmode);
 
     qemuDomainObjExitMonitor(driver, vm);
 
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index babf9e6..b82a1a3 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4532,13 +4532,14 @@ qemuMonitorTransactionBackup(virJSONValue *actions,
 
 int
 qemuMonitorStartDirtyRateCalc(qemuMonitor *mon,
-                              int seconds)
+                              int seconds,
+                              qemuMonitorDirtyRateCalcMode mode)
 {
     VIR_DEBUG("seconds=%d", seconds);
 
     QEMU_CHECK_MONITOR(mon);
 
-    return qemuMonitorJSONStartDirtyRateCalc(mon, seconds);
+    return qemuMonitorJSONStartDirtyRateCalc(mon, seconds, mode);
 }
 
 
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 9b2e4e1..08e14c0 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1551,9 +1551,17 @@ qemuMonitorTransactionBackup(virJSONValue *actions,
                              const char *bitmap,
                              qemuMonitorTransactionBackupSyncMode syncmode);
 
+typedef enum {
+    VIR_DOMAIN_DIRTYRATE_CALC_MODE_PAGE_SAMPLING = 0,
+    VIR_DOMAIN_DIRTYRATE_CALC_MODE_DIRTY_BITMAP,
+    VIR_DOMAIN_DIRTYRATE_CALC_MODE_DIRTY_RING,
+    VIR_DOMAIN_DIRTYRATE_CALC_MODE_LAST,
+} qemuMonitorDirtyRateCalcMode;
+
 int
 qemuMonitorStartDirtyRateCalc(qemuMonitor *mon,
-                              int seconds);
+                              int seconds,
+                              qemuMonitorDirtyRateCalcMode mode);
 
 typedef struct _qemuMonitorDirtyRateInfo qemuMonitorDirtyRateInfo;
 struct _qemuMonitorDirtyRateInfo {
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index b0b5136..afbd721 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -8695,18 +8695,34 @@ qemuMonitorJSONGetCPUMigratable(qemuMonitor *mon,
                                   migratable);
 }
 
+VIR_ENUM_DECL(qemuMonitorDirtyRateCalcMode);
+VIR_ENUM_IMPL(qemuMonitorDirtyRateCalcMode,
+              VIR_DOMAIN_DIRTYRATE_CALC_MODE_LAST,
+              "page-sampling",
+              "dirty-bitmap",
+              "dirty-ring");
 
 int
 qemuMonitorJSONStartDirtyRateCalc(qemuMonitor *mon,
-                                  int seconds)
+                                  int seconds,
+                                  qemuMonitorDirtyRateCalcMode mode)
 {
     g_autoptr(virJSONValue) cmd = NULL;
     g_autoptr(virJSONValue) reply = NULL;
 
-    if (!(cmd = qemuMonitorJSONMakeCommand("calc-dirty-rate",
-                                           "i:calc-time", seconds,
-                                           NULL)))
-        return -1;
+    if (mode == VIR_DOMAIN_DIRTYRATE_CALC_MODE_PAGE_SAMPLING) {
+        if (!(cmd = qemuMonitorJSONMakeCommand("calc-dirty-rate",
+                                               "i:calc-time", seconds,
+                                               NULL)))
+            return -1;
+    } else {
+        const char *modestr = qemuMonitorDirtyRateCalcModeTypeToString(mode);
+        if (!(cmd = qemuMonitorJSONMakeCommand("calc-dirty-rate",
+                                               "i:calc-time", seconds,
+                                               "s:mode", modestr,
+                                               NULL)))
+            return -1;
+    }
 
     if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
         return -1;
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 64d9ebd..51f78f1 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -855,7 +855,8 @@ qemuMonitorJSONGetCPUMigratable(qemuMonitor *mon,
 
 int
 qemuMonitorJSONStartDirtyRateCalc(qemuMonitor *mon,
-                                  int seconds);
+                                  int seconds,
+                                  qemuMonitorDirtyRateCalcMode mode);
 
 int
 qemuMonitorJSONQueryDirtyRate(qemuMonitor *mon,
-- 
1.8.3.1





More information about the libvir-list mailing list