From: Hyman Huang(黄勇) <huangy81(a)chinatelecom.cn>
Add mode option to extend qemuDomainStartDirtyRateCalc API,
which is introduced since qemu >= 6.2.
Signed-off-by: Hyman Huang(黄勇) <huangy81(a)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