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