libvirt: support migration dirtyrate

Signed-off-by: yezengruan <yezengruan@huawei.com>
This commit is contained in:
yezengruan 2022-11-03 20:05:39 +08:00
parent 6e543ea6c2
commit 81e3aa2975
8 changed files with 960 additions and 1 deletions

View File

@ -101,7 +101,7 @@
Summary: Library providing a simple virtualization API
Name: libvirt
Version: 6.2.0
Release: 43
Release: 44
License: LGPLv2+
URL: https://libvirt.org/
@ -360,6 +360,13 @@ Patch0247: util-fix-cache-invalidation-of-swtpm-capabilities.patch
Patch0248: virnettlscontext-Drop-gnutls_dh_set_prime_bits.patch
Patch0249: virnettlscontext-Don-t-pass-static-key-length-to-gnu.patch
Patch0250: rpc-Fix-memory-leak-of-fds.patch
Patch0251: migration-dirtyrate-Introduce-virDomainStartDirtyRat.patch
Patch0252: migration-dirtyrate-Implement-qemuDomainStartDirtyRa.patch
Patch0253: migration-dirtyrate-Introduce-domdirtyrate-calc-virs.patch
Patch0254: migration-dirtyrate-Introduce-virDomainDirtyRateStat.patch
Patch0255: migration-dirtyrate-Implement-qemuMonitorQueryDirtyR.patch
Patch0256: migration-dirtyrate-Extend-dirtyrate-statistics-for-.patch
Patch0257: migration-dirtyrate-Introduce-command-virsh-domstats.patch
Requires: libvirt-daemon = %{version}-%{release}
Requires: libvirt-daemon-config-network = %{version}-%{release}
@ -2094,6 +2101,9 @@ exit 0
%changelog
* Thu Nov 03 2022 yezengruan <yezengruan@huawei.com> - 6.2.0-44
- libvirt: support migration dirtyrate
* Tue Oct 11 2022 wengyu <wengyu@isrc.iscas.ac.cn> - 6.2.0-43
- libvirt: Synchronize upstream patches according to issue I5OLYY

View File

@ -0,0 +1,133 @@
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

View File

@ -0,0 +1,178 @@
From d6dd8dba23726495026b721da0835f7916000f94 Mon Sep 17 00:00:00 2001
From: Hao Wang <wanghao232@huawei.com>
Date: Tue, 16 Mar 2021 20:32:46 +0800
Subject: [PATCH 2/7] migration/dirtyrate: Implement
qemuDomainStartDirtyRateCalc
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Implement qemuDomainStartDirtyRateCalc which calculates domain's memory
dirty rate calling qmp "calc-dirty-rate".
cherry-pick from fbe99823e2a1b30e770620b0b51930e15c88de00
Signed-off-by: Hao Wang <wanghao232@huawei.com>
Signed-off-by: Hyman Huang(黄勇) <huangy81@chinatelecom.cn>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_driver.c | 59 ++++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor.c | 12 ++++++++
src/qemu/qemu_monitor.h | 4 +++
src/qemu/qemu_monitor_json.c | 21 +++++++++++++
src/qemu/qemu_monitor_json.h | 4 +++
5 files changed, 100 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e7166e4af3..b0a4905279 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -23298,6 +23298,64 @@ qemuDomainHotpatchManage(virDomainPtr domain,
return ret;
}
+#define MIN_DIRTYRATE_CALC_PERIOD 1 /* supported min dirtyrate calculating time: 1s */
+#define MAX_DIRTYRATE_CALC_PERIOD 60 /* supported max dirtyrate calculating time: 60s */
+
+static int
+qemuDomainStartDirtyRateCalc(virDomainPtr dom,
+ int seconds,
+ unsigned int flags)
+{
+ virQEMUDriverPtr driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ qemuDomainObjPrivatePtr priv;
+ int ret = -1;
+
+ virCheckFlags(0, -1);
+
+ if (seconds < MIN_DIRTYRATE_CALC_PERIOD ||
+ seconds > MAX_DIRTYRATE_CALC_PERIOD) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("seconds=%d is invalid, please choose value within [%d, %d]."),
+ seconds,
+ MIN_DIRTYRATE_CALC_PERIOD,
+ MAX_DIRTYRATE_CALC_PERIOD);
+ return -1;
+ }
+
+ if (!(vm = qemuDomainObjFromDomain(dom)))
+ return -1;
+
+ if (virDomainStartDirtyRateCalcEnsureACL(dom->conn, vm->def) < 0)
+ goto cleanup;
+
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
+ goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto endjob;
+ }
+
+ VIR_DEBUG("Calculate dirty rate in next %d seconds", seconds);
+
+ priv = vm->privateData;
+ qemuDomainObjEnterMonitor(driver, vm);
+ ret = qemuMonitorStartDirtyRateCalc(priv->mon, seconds);
+
+ if (qemuDomainObjExitMonitor(driver, vm) < 0)
+ ret = -1;
+
+ endjob:
+ qemuDomainObjEndJob(driver, vm);
+
+ cleanup:
+ virDomainObjEndAPI(&vm);
+ return ret;
+}
+
+
static virHypervisorDriver qemuHypervisorDriver = {
.name = QEMU_DRIVER_NAME,
.connectURIProbe = qemuConnectURIProbe,
@@ -23538,6 +23596,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
.domainBackupBegin = qemuDomainBackupBegin, /* 6.0.0 */
.domainBackupGetXMLDesc = qemuDomainBackupGetXMLDesc, /* 6.0.0 */
.domainHotpatchManage = qemuDomainHotpatchManage, /* 6.2.0 */
+ .domainStartDirtyRateCalc = qemuDomainStartDirtyRateCalc, /* 6.2.0 */
};
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index ec79fa6368..cdfe5fbed9 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4615,3 +4615,15 @@ qemuMonitorTransactionBackup(virJSONValuePtr actions,
return qemuMonitorJSONTransactionBackup(actions, device, jobname, target,
bitmap, syncmode);
}
+
+
+int
+qemuMonitorStartDirtyRateCalc(qemuMonitorPtr mon,
+ int seconds)
+{
+ VIR_DEBUG("seconds=%d", seconds);
+
+ QEMU_CHECK_MONITOR(mon);
+
+ return qemuMonitorJSONStartDirtyRateCalc(mon, seconds);
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 73c8af9e78..7b859155c3 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1425,3 +1425,7 @@ qemuMonitorTransactionBackup(virJSONValuePtr actions,
const char *target,
const char *bitmap,
qemuMonitorTransactionBackupSyncMode syncmode);
+
+int
+qemuMonitorStartDirtyRateCalc(qemuMonitorPtr mon,
+ int seconds);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index cc6644c9c3..fad9a2c233 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -9374,3 +9374,24 @@ qemuMonitorJSONGetJobInfo(qemuMonitorPtr mon,
return 0;
}
+
+int
+qemuMonitorJSONStartDirtyRateCalc(qemuMonitorPtr mon,
+ int seconds)
+{
+ g_autoptr(virJSONValue) cmd = NULL;
+ g_autoptr(virJSONValue) reply = NULL;
+
+ if (!(cmd = qemuMonitorJSONMakeCommand("calc-dirty-rate",
+ "i:calc-time", seconds,
+ NULL)))
+ return -1;
+
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ return -1;
+
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ return -1;
+
+ return 0;
+}
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 2c0e3ec07a..048e7c267c 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -691,3 +691,7 @@ int qemuMonitorJSONSetDBusVMStateIdList(qemuMonitorPtr mon,
const char *vmstatepath,
const char **list)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+
+int
+qemuMonitorJSONStartDirtyRateCalc(qemuMonitorPtr mon,
+ int seconds);
--
2.27.0

View File

@ -0,0 +1,168 @@
From c89672b2f41e1905b3b6e4fd0e37b709f629c422 Mon Sep 17 00:00:00 2001
From: Hao Wang <wanghao232@huawei.com>
Date: Tue, 16 Mar 2021 20:32:49 +0800
Subject: [PATCH 5/7] migration/dirtyrate: Implement qemuMonitorQueryDirtyRate
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Implement qemuMonitorQueryDirtyRate which query domain's memory
dirty rate calling qmp "query-dirty-rate".
cherry-pick from 4ae60b1cafec45209198d5ef2e1300474d63f327
Signed-off-by: Hao Wang <wanghao232@huawei.com>
Signed-off-by: Hyman Huang(黄勇) <huangy81@chinatelecom.cn>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_monitor.c | 12 ++++++
src/qemu/qemu_monitor.h | 15 +++++++
src/qemu/qemu_monitor_json.c | 79 ++++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 4 ++
4 files changed, 110 insertions(+)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index cdfe5fbed9..704c45d77d 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4627,3 +4627,15 @@ qemuMonitorStartDirtyRateCalc(qemuMonitorPtr mon,
return qemuMonitorJSONStartDirtyRateCalc(mon, seconds);
}
+
+
+int
+qemuMonitorQueryDirtyRate(qemuMonitorPtr mon,
+ qemuMonitorDirtyRateInfoPtr info)
+{
+ VIR_DEBUG("info=%p", info);
+
+ QEMU_CHECK_MONITOR(mon);
+
+ return qemuMonitorJSONQueryDirtyRate(mon, info);
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 7b859155c3..9c797d5ff5 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1429,3 +1429,18 @@ qemuMonitorTransactionBackup(virJSONValuePtr actions,
int
qemuMonitorStartDirtyRateCalc(qemuMonitorPtr mon,
int seconds);
+
+typedef struct _qemuMonitorDirtyRateInfo qemuMonitorDirtyRateInfo;
+typedef qemuMonitorDirtyRateInfo *qemuMonitorDirtyRateInfoPtr;
+
+struct _qemuMonitorDirtyRateInfo {
+ int status; /* the status of last dirtyrate calculation,
+ one of virDomainDirtyRateStatus */
+ int calcTime; /* the period of dirtyrate calculation */
+ long long startTime; /* the start time of dirtyrate calculation */
+ long long dirtyRate; /* the dirtyrate in MiB/s */
+};
+
+int
+qemuMonitorQueryDirtyRate(qemuMonitorPtr mon,
+ qemuMonitorDirtyRateInfoPtr info);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index fad9a2c233..3ec7fc84f5 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -9395,3 +9395,82 @@ qemuMonitorJSONStartDirtyRateCalc(qemuMonitorPtr mon,
return 0;
}
+
+VIR_ENUM_DECL(qemuMonitorDirtyRateStatus);
+VIR_ENUM_IMPL(qemuMonitorDirtyRateStatus,
+ VIR_DOMAIN_DIRTYRATE_LAST,
+ "unstarted",
+ "measuring",
+ "measured");
+
+static int
+qemuMonitorJSONExtractDirtyRateInfo(virJSONValuePtr data,
+ qemuMonitorDirtyRateInfoPtr info)
+{
+ const char *statusstr;
+ int status;
+
+ if (!(statusstr = virJSONValueObjectGetString(data, "status"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-dirty-rate reply was missing 'status' data"));
+ return -1;
+ }
+
+ if ((status = qemuMonitorDirtyRateStatusTypeFromString(statusstr)) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unknown dirty rate status: %s"), statusstr);
+ return -1;
+ }
+ info->status = status;
+
+ /* `query-dirty-rate` replies `dirty-rate` data only if the status of the latest
+ * calculation is `measured`.
+ */
+ if ((info->status == VIR_DOMAIN_DIRTYRATE_MEASURED) &&
+ (virJSONValueObjectGetNumberLong(data, "dirty-rate", &info->dirtyRate) < 0)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-dirty-rate reply was missing 'dirty-rate' data"));
+ return -1;
+ }
+
+ if (virJSONValueObjectGetNumberLong(data, "start-time", &info->startTime) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-dirty-rate reply was missing 'start-time' data"));
+ return -1;
+ }
+
+ if (virJSONValueObjectGetNumberInt(data, "calc-time", &info->calcTime) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-dirty-rate reply was missing 'calc-time' data"));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+qemuMonitorJSONQueryDirtyRate(qemuMonitorPtr mon,
+ qemuMonitorDirtyRateInfoPtr info)
+{
+ g_autoptr(virJSONValue) cmd = NULL;
+ g_autoptr(virJSONValue) reply = NULL;
+ virJSONValuePtr data = NULL;
+
+ if (!(cmd = qemuMonitorJSONMakeCommand("query-dirty-rate", NULL)))
+ return -1;
+
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ return -1;
+
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ return -1;
+
+ if (!(data = virJSONValueObjectGetObject(reply, "return"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-dirty-rate reply was missing 'return' data"));
+ return -1;
+ }
+
+ return qemuMonitorJSONExtractDirtyRateInfo(data, info);
+}
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 048e7c267c..531ff59a00 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -695,3 +695,7 @@ int qemuMonitorJSONSetDBusVMStateIdList(qemuMonitorPtr mon,
int
qemuMonitorJSONStartDirtyRateCalc(qemuMonitorPtr mon,
int seconds);
+
+int
+qemuMonitorJSONQueryDirtyRate(qemuMonitorPtr mon,
+ qemuMonitorDirtyRateInfoPtr info);
--
2.27.0

View File

@ -0,0 +1,97 @@
From a914cfe2abd42395cc1f4cab9c435d82fdd697cb Mon Sep 17 00:00:00 2001
From: Hao Wang <wanghao232@huawei.com>
Date: Tue, 16 Mar 2021 20:32:51 +0800
Subject: [PATCH 7/7] migration/dirtyrate: Introduce command 'virsh domstats
--dirtyrate'
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Introduce command 'virsh domstats --dirtyrate' for reporting memory
dirty rate information. The info is listed as:
Domain: 'vm0'
dirtyrate.calc_status=2
dirtyrate.calc_start_time=1534523
dirtyrate.calc_period=1
dirtyrate.megabytes_per_second=5
cherry-pick from 5be6decbb131a2139161bf8ec4575f45997e31ee
Signed-off-by: Hao Wang <wanghao232@huawei.com>
Signed-off-by: Hyman Huang(黄勇) <huangy81@chinatelecom.cn>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
docs/manpages/virsh.rst | 16 ++++++++++++++--
tools/virsh-domain-monitor.c | 7 +++++++
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index b44e8f9301..3d4fadc041 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -2208,7 +2208,7 @@ domstats
domstats [--raw] [--enforce] [--backing] [--nowait] [--state]
[--cpu-total] [--balloon] [--vcpu] [--interface]
- [--block] [--perf] [--iothread] [--memory]
+ [--block] [--perf] [--iothread] [--memory] [--dirtyrate]
[[--list-active] [--list-inactive]
[--list-persistent] [--list-transient] [--list-running]y
[--list-paused] [--list-shutoff] [--list-other]] | [domain ...]
@@ -2227,7 +2227,8 @@ behavior use the *--raw* flag.
The individual statistics groups are selectable via specific flags. By
default all supported statistics groups are returned. Supported
statistics groups flags are: *--state*, *--cpu-total*, *--balloon*,
-*--vcpu*, *--interface*, *--block*, *--perf*, *--iothread*, *--memory*.
+*--vcpu*, *--interface*, *--block*, *--perf*, *--iothread*, *--memory*,
+*--dirtyrate*.
Note that - depending on the hypervisor type and version or the domain state
- not all of the following statistics may be returned.
@@ -2411,6 +2412,17 @@ not available for statistical purposes.
bytes consumed by @vcpus that passing through all memory controllers, either
local or remote controller.
+*--dirtyrate* returns:
+
+* ``dirtyrate.calc_status`` - the status of last memory dirty rate
+ calculation, returned as number from virDomainDirtyRateStatus enum.
+* ``dirtyrate.calc_start_time`` - the start time of last memory dirty
+ rate calculation.
+* ``dirtyrate.calc_period`` - the period of last memory dirty rate
+ calculation.
+* ``dirtyrate.megabytes_per_second`` - the calculated memory dirty
+ rate in MiB/s.
+
Selecting a specific statistics groups doesn't guarantee that the
daemon supports the selected group of stats. Flag *--enforce*
diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index 74ff369597..e692fefa2c 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -2130,6 +2130,10 @@ static const vshCmdOptDef opts_domstats[] = {
.type = VSH_OT_BOOL,
.help = N_("report domain memory usage"),
},
+ {.name = "dirtyrate",
+ .type = VSH_OT_BOOL,
+ .help = N_("report domain dirty rate information"),
+ },
{.name = "list-active",
.type = VSH_OT_BOOL,
.help = N_("list only active domains"),
@@ -2249,6 +2253,9 @@ cmdDomstats(vshControl *ctl, const vshCmd *cmd)
if (vshCommandOptBool(cmd, "memory"))
stats |= VIR_DOMAIN_STATS_MEMORY;
+ if (vshCommandOptBool(cmd, "dirtyrate"))
+ stats |= VIR_DOMAIN_STATS_DIRTYRATE;
+
if (vshCommandOptBool(cmd, "list-active"))
flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE;
--
2.27.0

View File

@ -0,0 +1,129 @@
From f254d3fe1e7b50c850c634adf554e4e384a4abad Mon Sep 17 00:00:00 2001
From: Hao Wang <wanghao232@huawei.com>
Date: Tue, 16 Mar 2021 20:32:47 +0800
Subject: [PATCH 3/7] migration/dirtyrate: Introduce domdirtyrate-calc virsh
api
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Introduce domdirtyrate-calc virsh api to start calculating domain's
memory dirty rate:
# virsh domdirtyrate-calc <domain> [--seconds <sec>]
cherry-pick from a2ae2dad062e8b23efac132488ce6aaea388de51
Signed-off-by: Hao Wang <wanghao232@huawei.com>
Signed-off-by: Hyman Huang(黄勇) <huangy81@chinatelecom.cn>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
docs/manpages/virsh.rst | 17 ++++++++++++
tools/virsh-domain.c | 58 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 75 insertions(+)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index dc404ddfe8..b44e8f9301 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -1696,6 +1696,23 @@ states other than "ok" or "error" the command also prints number of
seconds elapsed since the control interface entered its current state.
+domdirtyrate-calc
+-----------------
+
+**Syntax:**
+
+::
+
+ domdirtyrate-calc <domain> [--seconds <sec>]
+
+Calculate an active domain's memory dirty rate which may be expected by
+user in order to decide whether it's proper to be migrated out or not.
+The ``seconds`` parameter can be used to calculate dirty rate in a
+specific time which allows 60s at most now and would be default to 1s
+if missing. The calculated dirty rate information is available by calling
+'domstats --dirtyrate'.
+
+
domdisplay
----------
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index b5375ebd3e..0d42496898 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -14399,6 +14399,58 @@ cmdHotpatch(vshControl *ctl,
return true;
}
+/*
+ * "domdirtyrate" command
+ */
+static const vshCmdInfo info_domdirtyrate_calc[] = {
+ {.name = "help",
+ .data = N_("Calculate a vm's memory dirty rate")
+ },
+ {.name = "desc",
+ .data = N_("Calculate memory dirty rate of a domain in order to "
+ "decide whether it's proper to be migrated out or not.\n"
+ "The calculated dirty rate information is available by "
+ "calling 'domstats --dirtyrate'.")
+ },
+ {.name = NULL}
+};
+
+static const vshCmdOptDef opts_domdirtyrate_calc[] = {
+ VIRSH_COMMON_OPT_DOMAIN_FULL(0),
+ {.name = "seconds",
+ .type = VSH_OT_INT,
+ .help = N_("calculate memory dirty rate within specified seconds, "
+ "the supported value range from 1 to 60, default to 1.")
+ },
+ {.name = NULL}
+};
+
+static bool
+cmdDomDirtyRateCalc(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom = NULL;
+ int seconds = 1; /* the default value is 1 */
+ bool ret = false;
+
+ if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
+ return false;
+
+ if (vshCommandOptInt(ctl, cmd, "seconds", &seconds) < 0)
+ goto cleanup;
+
+ if (virDomainStartDirtyRateCalc(dom, seconds, 0) < 0)
+ goto cleanup;
+
+ vshPrintExtra(ctl, _("Start to calculate domain's memory "
+ "dirty rate successfully.\n"));
+ ret = true;
+
+ cleanup:
+ virshDomainFree(dom);
+ return ret;
+}
+
+
const vshCmdDef domManagementCmds[] = {
{.name = "attach-device",
.handler = cmdAttachDevice,
@@ -15032,5 +15084,11 @@ const vshCmdDef domManagementCmds[] = {
.info = info_hotpatch,
.flags = 0
},
+ {.name = "domdirtyrate-calc",
+ .handler = cmdDomDirtyRateCalc,
+ .opts = opts_domdirtyrate_calc,
+ .info = info_domdirtyrate_calc,
+ .flags = 0
+ },
{.name = NULL}
};
--
2.27.0

View File

@ -0,0 +1,52 @@
From 752ee833cda682db3cb0a38b094f3a2ec1317486 Mon Sep 17 00:00:00 2001
From: Hao Wang <wanghao232@huawei.com>
Date: Tue, 16 Mar 2021 20:32:48 +0800
Subject: [PATCH 4/7] migration/dirtyrate: Introduce virDomainDirtyRateStatus
enum
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Introduce virDomainDirtyRateStatus enum.
cherry-pick from a0c7f61f37c087dcc1fadfba9f5308b0bcb5784a
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 | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 24df273045..01dc64f4f4 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -5011,6 +5011,24 @@ virDomainHotpatchManage(virDomainPtr domain,
const char *id,
unsigned int flags);
+/**
+ * virDomainDirtyRateStatus:
+ *
+ * Details on the cause of a dirty rate calculation status.
+ */
+typedef enum {
+ VIR_DOMAIN_DIRTYRATE_UNSTARTED = 0, /* the dirtyrate calculation has
+ not been started */
+ VIR_DOMAIN_DIRTYRATE_MEASURING = 1, /* the dirtyrate calculation is
+ measuring */
+ VIR_DOMAIN_DIRTYRATE_MEASURED = 2, /* the dirtyrate calculation is
+ completed */
+
+# ifdef VIR_ENUM_SENTINELS
+ VIR_DOMAIN_DIRTYRATE_LAST
+# endif
+} virDomainDirtyRateStatus;
+
int virDomainStartDirtyRateCalc(virDomainPtr domain,
int seconds,
unsigned int flags);
--
2.27.0

View File

@ -0,0 +1,192 @@
From cd1852cbccb7a9b5055bcc11d1ed3b4b26c4d213 Mon Sep 17 00:00:00 2001
From: Hao Wang <wanghao232@huawei.com>
Date: Tue, 16 Mar 2021 20:32:45 +0800
Subject: [PATCH 1/7] migration/dirtyrate: Introduce
virDomainStartDirtyRateCalc API
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Introduce virDomainStartDirtyRateCalc API for start calculation of
a domain's memory dirty rate with a specified time.
cherry-pick from df5c5c3e60e5a3b8e9b827cc51984f055ba1ce01
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 | 4 +++
src/driver-hypervisor.h | 6 +++++
src/libvirt-domain.c | 44 ++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 1 +
src/remote/remote_driver.c | 1 +
src/remote/remote_protocol.x | 12 +++++++++
src/remote_protocol-structs | 6 +++++
7 files changed, 74 insertions(+)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 4ab0c9c0b2..24df273045 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -5011,4 +5011,8 @@ virDomainHotpatchManage(virDomainPtr domain,
const char *id,
unsigned int flags);
+int virDomainStartDirtyRateCalc(virDomainPtr domain,
+ int seconds,
+ unsigned int flags);
+
#endif /* LIBVIRT_DOMAIN_H */
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index afc21a0b3f..82f808905d 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -1394,6 +1394,11 @@ typedef char *
const char *id,
unsigned int flags);
+typedef int
+(*virDrvDomainStartDirtyRateCalc)(virDomainPtr domain,
+ int seconds,
+ unsigned int flags);
+
typedef struct _virHypervisorDriver virHypervisorDriver;
typedef virHypervisorDriver *virHypervisorDriverPtr;
@@ -1658,4 +1663,5 @@ struct _virHypervisorDriver {
virDrvDomainBackupBegin domainBackupBegin;
virDrvDomainBackupGetXMLDesc domainBackupGetXMLDesc;
virDrvDomainHotpatchManage domainHotpatchManage;
+ virDrvDomainStartDirtyRateCalc domainStartDirtyRateCalc;
};
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 3cf6bcb3b4..974a5a5f36 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -12800,3 +12800,47 @@ virDomainHotpatchManage(virDomainPtr domain,
virDispatchError(conn);
return NULL;
}
+
+
+/**
+ * virDomainStartDirtyRateCalc:
+ * @domain: a domain object
+ * @seconds: specified calculating time in seconds
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Calculate the current domain's memory dirty rate in next @seconds.
+ * The calculated dirty rate information is available by calling
+ * virConnectGetAllDomainStats.
+ *
+ * Returns 0 in case of success, -1 otherwise.
+ */
+int
+virDomainStartDirtyRateCalc(virDomainPtr domain,
+ int seconds,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "seconds=%d, flags=0x%x", seconds, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainStartDirtyRateCalc) {
+ int ret;
+ ret = conn->driver->domainStartDirtyRateCalc(domain, seconds, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 0ad0b9e489..f006516208 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -876,5 +876,6 @@ LIBVIRT_6.0.0 {
LIBVIRT_6.2.0 {
global:
virDomainHotpatchManage;
+ virDomainStartDirtyRateCalc;
} LIBVIRT_6.0.0;
# .... define new API here using predicted next version number ....
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 1202d44017..e8ccbcb4f8 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -8685,6 +8685,7 @@ static virHypervisorDriver hypervisor_driver = {
.domainBackupBegin = remoteDomainBackupBegin, /* 6.0.0 */
.domainBackupGetXMLDesc = remoteDomainBackupGetXMLDesc, /* 6.0.0 */
.domainHotpatchManage = remoteDomainHotpatchManage, /* 6.2.0 */
+ .domainStartDirtyRateCalc = remoteDomainStartDirtyRateCalc, /* 6.2.0 */
};
static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index ee13075ce1..d89cc1a087 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -3783,6 +3783,12 @@ struct remote_domain_hotpatch_manage_ret {
remote_string info;
};
+struct remote_domain_start_dirty_rate_calc_args {
+ remote_nonnull_domain dom;
+ int seconds;
+ unsigned int flags;
+};
+
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
@@ -6682,6 +6688,12 @@ enum remote_procedure {
*/
REMOTE_PROC_DOMAIN_BACKUP_GET_XML_DESC = 422,
+ /**
+ * @generate: both
+ * @acl: domain:read
+ */
+ REMOTE_PROC_DOMAIN_START_DIRTY_RATE_CALC = 427,
+
/**
* @generate: both
* @acl: domain:read
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index bae0f0b545..1e81814690 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -3135,6 +3135,11 @@ struct remote_domain_backup_get_xml_desc_args {
struct remote_domain_backup_get_xml_desc_ret {
remote_nonnull_string xml;
};
+struct remote_domain_start_dirty_rate_calc_args {
+ remote_nonnull_domain dom;
+ int seconds;
+ u_int flags;
+};
enum remote_procedure {
REMOTE_PROC_CONNECT_OPEN = 1,
REMOTE_PROC_CONNECT_CLOSE = 2,
@@ -3558,4 +3563,5 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_AGENT_SET_RESPONSE_TIMEOUT = 420,
REMOTE_PROC_DOMAIN_BACKUP_BEGIN = 421,
REMOTE_PROC_DOMAIN_BACKUP_GET_XML_DESC = 422,
+ REMOTE_PROC_DOMAIN_START_DIRTY_RATE_CALC = 427,
};
--
2.27.0