Extend dirtyrate statistics for domGetStats to display the information of a domain's memory dirty rate produced by domainStartDirtyRateCalc. Signed-off-by: Hao Wang <wanghao232@xxxxxxxxxx> --- 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 b05bb94131..03c119fe26 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -2185,6 +2185,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 91001fc4ed..83ff7df9fe 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -11887,6 +11887,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 8836d9fd16..f3f8caab44 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -18577,6 +18577,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, @@ -18599,6 +18649,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.23.0