From: Chun Feng Wu <danielwuwy(a)163.com>
This change contains QMP requests for ThrottleGroup
* 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 <danielwuwy(a)163.com>
---
src/qemu/qemu_monitor.c | 34 +++++++++
src/qemu/qemu_monitor.h | 14 ++++
src/qemu/qemu_monitor_json.c | 134 +++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 14 ++++
4 files changed, 196 insertions(+)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 7f65c23748..60f5e25ddd 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -2997,6 +2997,40 @@ qemuMonitorGetBlockIoThrottle(qemuMonitor *mon,
}
+int
+qemuMonitorThrottleGroupLimits(virJSONValue *limits,
+ const virDomainThrottleGroupDef *group)
+{
+ return qemuMonitorMakeThrottleGroupLimits(limits, group);
+}
+
+
+int
+qemuMonitorUpdateThrottleGroup(qemuMonitor *mon,
+ const char *qomid,
+ virDomainBlockIoTuneInfo *info)
+{
+ VIR_DEBUG("qomid=%s, info=%p", 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", 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 57d1b45bf5..438e8fe19f 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1064,6 +1064,20 @@ int qemuMonitorGetBlockIoThrottle(qemuMonitor *mon,
const char *qdevid,
virDomainBlockIoTuneInfo *reply);
+int
+qemuMonitorThrottleGroupLimits(virJSONValue *limits,
+ 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 2db38c1007..8e171c1fe4 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -4646,6 +4646,140 @@ int qemuMonitorJSONGetBlockIoThrottle(qemuMonitor *mon,
return qemuMonitorJSONBlockIoThrottleInfo(devices, qdevid, reply);
}
+
+int
+qemuMonitorMakeThrottleGroupLimits(virJSONValue *limits,
+ const virDomainThrottleGroupDef *group)
+{
+ if (virJSONValueObjectAdd(&limits,
+ "P:bps-total", group->total_bytes_sec,
+ "P:bps-read", group->read_bytes_sec,
+ "P:bps-write", group->write_bytes_sec,
+ "P:iops-total", group->total_iops_sec,
+ "P:iops-read", group->read_iops_sec,
+ "P:iops-write", group->write_iops_sec,
+ "P:bps-total-max",
group->total_bytes_sec_max,
+ "P:bps-read-max", group->read_bytes_sec_max,
+ "P:bps-write-max",
group->write_bytes_sec_max,
+ "P:iops-total-max",
group->total_iops_sec_max,
+ "P:iops-read-max", group->read_iops_sec_max,
+ "P:iops-write-max",
group->write_iops_sec_max,
+ "P:iops-size", group->size_iops_sec,
+ /* avoid error from QEMU: "the burst length cannot be
0" for throttlelimits
+ * when setting max-length
+ */
+ "P:bps-total-max-length",
group->total_bytes_sec_max_length,
+ "P:bps-read-max-length",
group->read_bytes_sec_max_length,
+ "P:bps-write-max-length",
group->write_bytes_sec_max_length,
+ "P:iops-total-max-length",
group->total_iops_sec_max_length,
+ "P:iops-read-max-length",
group->read_iops_sec_max_length,
+ "P:iops-write-max-length",
group->write_iops_sec_max_length,
+ NULL) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+int
+qemuMonitorJSONUpdateThrottleGroup(qemuMonitor *mon,
+ const char *qomid,
+ virDomainBlockIoTuneInfo *info)
+{
+ g_autoptr(virJSONValue) cmd = NULL;
+ g_autoptr(virJSONValue) result = NULL;
+ g_autoptr(virJSONValue) limits = virJSONValueNewObject();
+ /* prefix group name with "throttle-" in QOM */
+ g_autofree char *prefixed_group_name = g_strdup_printf("throttle-%s",
qomid);
+
+ if (qemuMonitorMakeThrottleGroupLimits(limits, info) < 0)
+ return -1;
+
+ if (!(cmd = qemuMonitorJSONMakeCommand("qom-set",
+ "s:property", "limits",
+ "s:path", prefixed_group_name,
+ "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, \
+ _("value of throttle group field '%1$s' is
malformed"), \
+ #STORE); \
+ return -1; \
+ } \
+ }
+
+
+int
+qemuMonitorJSONGetThrottleGroup(qemuMonitor *mon,
+ const char *gname,
+ virDomainBlockIoTuneInfo *reply)
+{
+ g_autoptr(virJSONValue) cmd = NULL;
+ g_autoptr(virJSONValue) result = NULL;
+ g_autofree char *groupCopy = NULL;
+ virJSONValue *ret;
+
+ /* prefix group name with "throttle-" in QOM */
+ g_autofree char *path = g_strdup_printf("/objects/throttle-%s", gname);
+ if (!(cmd = qemuMonitorJSONMakeCommand("qom-get",
+ "s:path", path,
+ "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)))
+ 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 921dd34ed2..f90fc336bc 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -404,6 +404,20 @@ qemuMonitorJSONSetBlockIoThrottle(qemuMonitor *mon,
const char *qomid,
virDomainBlockIoTuneInfo *info);
+int
+qemuMonitorMakeThrottleGroupLimits(virJSONValue *limits,
+ 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.43.0