From: Chun Feng Wu <wucf@xxxxxxxxxxxxx> * ThrottleGroup is updated through "qemuMonitorJSONUpdateThrottleGroup" * ThrottleGroup is retrieved through "qemuMonitorJSONGetThrottleGroup" * ThrottleGroup is deleted by reusing "qemuMonitorDelObject" * ThrottleGroup is added by reusing "qemuMonitorAddObject" * "qemuMonitorMakeThrottleGroupLimits" will be used by building qemu cmd as well Signed-off-by: Chun Feng Wu <wucf@xxxxxxxxxxxxx> --- src/qemu/qemu_monitor.c | 29 ++++++++ src/qemu/qemu_monitor.h | 10 +++ src/qemu/qemu_monitor_json.c | 135 +++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 13 ++++ 4 files changed, 187 insertions(+) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 34e2ccab97..0c0bfe3449 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -2995,6 +2995,35 @@ qemuMonitorGetBlockIoThrottle(qemuMonitor *mon, return qemuMonitorJSONGetBlockIoThrottle(mon, qdevid, reply); } +virJSONValue *qemuMonitorThrottleGroupLimits(const virDomainThrottleGroupDef *group) +{ + return qemuMonitorMakeThrottleGroupLimits(group); +} + +int +qemuMonitorUpdateThrottleGroup(qemuMonitor *mon, + const char *qomid, + virDomainBlockIoTuneInfo *info) +{ + VIR_DEBUG("qomid=%s, info=%p", NULLSTR(qomid), info); + + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONUpdateThrottleGroup(mon, qomid, info); +} + + +int +qemuMonitorGetThrottleGroup(qemuMonitor *mon, + const char *groupname, + virDomainBlockIoTuneInfo *reply) +{ + VIR_DEBUG("throttle-group=%s, reply=%p", NULLSTR(groupname), reply); + + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONGetThrottleGroup(mon, groupname, reply); +} int qemuMonitorVMStatusToPausedReason(const char *status) diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 6e81945201..37a0307d40 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -1061,6 +1061,16 @@ int qemuMonitorGetBlockIoThrottle(qemuMonitor *mon, const char *qdevid, virDomainBlockIoTuneInfo *reply); +virJSONValue *qemuMonitorThrottleGroupLimits(const virDomainThrottleGroupDef *group); + +int qemuMonitorUpdateThrottleGroup(qemuMonitor *mon, + const char *qomid, + virDomainBlockIoTuneInfo *info); + +int qemuMonitorGetThrottleGroup(qemuMonitor *mon, + const char *groupname, + virDomainBlockIoTuneInfo *reply); + int qemuMonitorSystemWakeup(qemuMonitor *mon); int qemuMonitorGetVersion(qemuMonitor *mon, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index eb84a3d938..ab7d2f1298 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -4633,6 +4633,141 @@ int qemuMonitorJSONGetBlockIoThrottle(qemuMonitor *mon, return qemuMonitorJSONBlockIoThrottleInfo(devices, qdevid, reply); } +static void virJSONValueLimitsAppendPositiveNumberLong(virJSONValue *limits, + const char *name, + unsigned long long value) +{ + /* avoid error from QEMU: "the burst length cannot be 0" for throttlelimits + * when seeting max-length + */ + if (value > 0) { + virJSONValueObjectAppendNumberLong(limits, name, value); + } +} + +virJSONValue * +qemuMonitorMakeThrottleGroupLimits(const virDomainThrottleGroupDef *group) +{ + g_autoptr(virJSONValue) limits = virJSONValueNewObject(); + + virJSONValueObjectAppendNumberLong(limits, "bps-total", group->total_bytes_sec); + virJSONValueObjectAppendNumberLong(limits, "bps-read", group->read_bytes_sec); + virJSONValueObjectAppendNumberLong(limits, "bps-write", group->write_bytes_sec); + virJSONValueObjectAppendNumberLong(limits, "iops-total", group->total_iops_sec); + virJSONValueObjectAppendNumberLong(limits, "iops-read", group->read_iops_sec); + virJSONValueObjectAppendNumberLong(limits, "iops-write", group->write_iops_sec); + virJSONValueObjectAppendNumberLong(limits, "bps-total-max", group->total_bytes_sec_max); + virJSONValueObjectAppendNumberLong(limits, "bps-read-max", group->read_bytes_sec_max); + virJSONValueObjectAppendNumberLong(limits, "bps-write-max", group->write_bytes_sec_max); + virJSONValueObjectAppendNumberLong(limits, "iops-total-max", group->total_iops_sec_max); + virJSONValueObjectAppendNumberLong(limits, "iops-read-max", group->read_iops_sec_max); + virJSONValueObjectAppendNumberLong(limits, "iops-write-max", group->write_iops_sec_max); + virJSONValueObjectAppendNumberLong(limits, "iops-size", group->size_iops_sec); + virJSONValueLimitsAppendPositiveNumberLong(limits, "bps-total-max-length", group->total_bytes_sec_max_length); + virJSONValueLimitsAppendPositiveNumberLong(limits, "bps-read-max-length", group->read_bytes_sec_max_length); + virJSONValueLimitsAppendPositiveNumberLong(limits, "bps-write-max-length", group->write_bytes_sec_max_length); + virJSONValueLimitsAppendPositiveNumberLong(limits, "iops-total-max-length", group->total_iops_sec_max_length); + virJSONValueLimitsAppendPositiveNumberLong(limits, "iops-read-max-length", group->read_iops_sec_max_length); + virJSONValueLimitsAppendPositiveNumberLong(limits, "iops-write-max-length", group->write_iops_sec_max_length); + + return g_steal_pointer(&limits); +} + +int qemuMonitorJSONUpdateThrottleGroup(qemuMonitor *mon, + const char *qomid, + virDomainBlockIoTuneInfo *info) +{ + g_autoptr(virJSONValue) cmd = NULL; + g_autoptr(virJSONValue) result = NULL; + g_autoptr(virJSONValue) limits = NULL; + + limits = qemuMonitorMakeThrottleGroupLimits(info); + + if (!(cmd = qemuMonitorJSONMakeCommand("qom-set", + "s:property", "limits", + "s:path", qomid, + "a:value", &limits, + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &result) < 0) + return -1; + + if (qemuMonitorJSONCheckError(cmd, result) < 0) + return -1; + + return 0; +} + +#define GET_THROTTLE_GROUP_VALUE(FIELD, STORE) \ + if (virJSONValueObjectHasKey(ret, FIELD)) { \ + if (virJSONValueObjectGetNumberUlong(ret, FIELD, &reply->STORE) < 0) { \ + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, \ + _("throttle group field '%1$s' missing in qemu's output"), \ + #STORE); \ + return -1; \ + } \ + } + +int qemuMonitorJSONGetThrottleGroup(qemuMonitor *mon, + const char *gname, + virDomainBlockIoTuneInfo *reply) +{ + char fullpath[100]; + g_autoptr(virJSONValue) cmd = NULL; + g_autoptr(virJSONValue) result = NULL; + g_autofree char *groupCopy = NULL; + virJSONValue *ret; + + + g_snprintf(fullpath, sizeof(fullpath), "%s%s", "/objects/", gname); + if (!(cmd = qemuMonitorJSONMakeCommand("qom-get", + "s:path", fullpath, + "s:property", "limits", + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &result) < 0) + return -1; + + if (qemuMonitorJSONCheckError(cmd, result) < 0) + return -1; + + if (!(ret = qemuMonitorJSONGetReply(cmd, result, VIR_JSON_TYPE_OBJECT))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("throttle group entry was not in expected format")); + return -1; + } + + GET_THROTTLE_GROUP_VALUE("bps-total", total_bytes_sec); + GET_THROTTLE_GROUP_VALUE("bps-read", read_bytes_sec); + GET_THROTTLE_GROUP_VALUE("bps-write", write_bytes_sec); + GET_THROTTLE_GROUP_VALUE("iops-total", total_iops_sec); + GET_THROTTLE_GROUP_VALUE("iops-read", read_iops_sec); + GET_THROTTLE_GROUP_VALUE("iops-write", write_iops_sec); + + GET_THROTTLE_GROUP_VALUE("bps-total-max", total_bytes_sec_max); + GET_THROTTLE_GROUP_VALUE("bps-read-max", read_bytes_sec_max); + GET_THROTTLE_GROUP_VALUE("bps-write-max", write_bytes_sec_max); + GET_THROTTLE_GROUP_VALUE("iops-total-max", total_iops_sec_max); + GET_THROTTLE_GROUP_VALUE("iops-read-max", read_iops_sec_max); + GET_THROTTLE_GROUP_VALUE("iops-write-max", write_iops_sec_max); + GET_THROTTLE_GROUP_VALUE("iops-size", size_iops_sec); + + GET_THROTTLE_GROUP_VALUE("bps-total-max-length", total_bytes_sec_max_length); + GET_THROTTLE_GROUP_VALUE("bps-read-max-length", read_bytes_sec_max_length); + GET_THROTTLE_GROUP_VALUE("bps-write-max-length", write_bytes_sec_max_length); + GET_THROTTLE_GROUP_VALUE("iops-total-max-length", total_iops_sec_max_length); + GET_THROTTLE_GROUP_VALUE("iops-read-max-length", read_iops_sec_max_length); + GET_THROTTLE_GROUP_VALUE("iops-write-max-length", write_iops_sec_max_length); + + groupCopy = g_strdup(gname); + reply->group_name = g_steal_pointer(&groupCopy); + + return 0; +} +#undef GET_THROTTLE_GROUP_VALUE + int qemuMonitorJSONSystemWakeup(qemuMonitor *mon) { g_autoptr(virJSONValue) cmd = NULL; diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 9684660d86..b8ebb77b72 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -404,6 +404,19 @@ qemuMonitorJSONSetBlockIoThrottle(qemuMonitor *mon, const char *qomid, virDomainBlockIoTuneInfo *info); +virJSONValue * +qemuMonitorMakeThrottleGroupLimits(const virDomainThrottleGroupDef *group); + +int +qemuMonitorJSONUpdateThrottleGroup(qemuMonitor *mon, + const char *qomid, + virDomainBlockIoTuneInfo *info); + +int +qemuMonitorJSONGetThrottleGroup(qemuMonitor *mon, + const char *gname, + virDomainBlockIoTuneInfo *reply); + int qemuMonitorJSONGetBlockIoThrottle(qemuMonitor *mon, const char *qdevid, -- 2.34.1 _______________________________________________ Devel mailing list -- devel@xxxxxxxxxxxxxxxxx To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxx