Contrary to most APIs returning typed parameters, there are no constants
defined for the domain stats data keys. This is was because many of the
keys needs to be dynamically constructed using one or more array index
values.
It is possible to define constants while still supporting dynamic
array indexes by simply defining the prefixes and suffixes as constants.
The consuming code can then combine the constants with array index
value.
With this approach, it is practical to add constants for the domain stats
API keys.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
include/libvirt/libvirt-domain.h | 92 ++++++++++++++++++++++++++++++++
src/libvirt-domain.c | 19 +------
src/qemu/qemu_driver.c | 37 +++++++++----
3 files changed, 120 insertions(+), 28 deletions(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index fe2bbc48cb..e76d1d9319 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -3743,6 +3743,98 @@ struct _virDomainStatsRecord {
*/
#define VIR_DOMAIN_STATS_IOTHREAD_SUFFIX_POLL_SHRINK ".poll-shrink"
+
+/**
+ * VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_COUNT:
+ *
+ * The number of memory bandwidth monitors for this domain as an unsigned int.
+ *
+ * Since: 11.2.0
+ */
+#define VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_COUNT "memory.bandwidth.monitor.count"
+
+/**
+ * VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_PREFIX:
+ *
+ * The parameter name prefix to access each bandwith monitor entry.
+ * Concatenate the prefix, the entry number formatted as an unsigned integer
+ * and one of the memory bandwith suffix parameters to form a complete
+ * parameter name.
+ *
+ * Since: 11.2.0
+ */
+#define VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_PREFIX "memory.bandwidth.monitor."
+
+/**
+ * VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NAME:
+ *
+ * The name of the bandwidth monitor as a string.
+ *
+ * Since: 11.2.0
+ */
+#define VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NAME ".name"
+
+/**
+ * VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_VCPUS:
+ *
+ * The vcpu list of the bandwidth monitor as a string.
+ *
+ * Since: 11.2.0
+ */
+#define VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_VCPUS ".vcpus"
+
+/**
+ * VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_COUNT:
+ *
+ * The number of memory controllers in the bandwidth monitor.
+ *
+ * Since: 11.2.0
+ */
+#define VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_COUNT ".node.count"
+
+/**
+ * VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_PREFIX:
+ *
+ * The parameter name prefix to access each controller entry. Concatenate the
+ * bandwidth monitor prefix, the monitor entry number formatted as an unsigned
+ * integer, the controller prefix, the controller entry number formatted as an
+ * unsigned integer and one of the controller suffix parameters to form a
+ * complete parameter name.
+ *
+ * Since: 11.2.0
+ */
+#define VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_PREFIX ".node."
+
+/**
+ * VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_SUFFIX_ID:
+ *
+ * Host allocated memory controller id for the controller as an unsigned int.
+ *
+ * Since: 11.2.0
+ */
+#define VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_SUFFIX_ID ".id"
+
+/**
+ * VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_SUFFIX_BYTES_LOCAL:
+ *
+ * The accumulative bytes consumed by vcpus passing through the memory
+ * controller in the same processor that the scheduled host CPU belongs to as
+ * an unsigned long long.
+ *
+ * Since: 11.2.0
+ */
+#define VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_SUFFIX_BYTES_LOCAL ".bytes.local"
+
+/**
+ * VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_SUFFIX_BYTES_TOTAL:
+ *
+ * The accumulative bytes consumed by vcpus passing through all memory
+ * controllers, either local or remote, as an unsigned long long.
+ *
+ * Since: 11.2.0
+ */
+#define VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_SUFFIX_BYTES_TOTAL ".bytes.total"
+
/**
* virDomainStatsTypes:
*
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index e643fec02c..9111184d57 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -12316,23 +12316,8 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
* VIR_DOMAIN_STATS_MEMORY:
* Return memory bandwidth statistics and the usage information. The typed
* parameter keys are in this format:
- *
- * "memory.bandwidth.monitor.count" - the number of memory bandwidth
- * monitors for this domain
- * "memory.bandwidth.monitor.<num>.name" - the name of monitor <num>
- * "memory.bandwidth.monitor.<num>.vcpus" - the vcpu list of monitor <num>
- * "memory.bandwidth.monitor.<num>.node.count" - the number of memory
- * controller in monitor <num>
- * "memory.bandwidth.monitor.<num>.node.<index>.id" - host allocated memory
- * controller id for controller
- * <index> of monitor <num>
- * "memory.bandwidth.monitor.<num>.node.<index>.bytes.local" - the
- * accumulative bytes consumed by @vcpus that passing
- * through the memory controller in the same processor
- * that the scheduled host CPU belongs to.
- * "memory.bandwidth.monitor.<num>.node.<index>.bytes.total" - the total
- * bytes consumed by @vcpus that passing through all
- * memory controllers, either local or remote controller.
+ * The VIR_DOMAIN_STATS_MEMORY_* constants define the known typed
+ * parameter keys.
*
* VIR_DOMAIN_STATS_DIRTYRATE:
* Return memory dirty rate information. The typed parameter keys are in
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 76e121144d..d48e79d5c6 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16722,32 +16722,47 @@ qemuDomainGetStatsMemoryBandwidth(virQEMUDriver *driver,
if (nresdata == 0)
return;
- virTypedParamListAddUInt(params, nresdata, "memory.bandwidth.monitor.count");
+ virTypedParamListAddUInt(params, nresdata,
+ VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_COUNT);
for (i = 0; i < nresdata; i++) {
- virTypedParamListAddString(params, resdata[i]->name, "memory.bandwidth.monitor.%zu.name", i);
- virTypedParamListAddString(params, resdata[i]->vcpus, "memory.bandwidth.monitor.%zu.vcpus", i);
- virTypedParamListAddUInt(params, resdata[i]->nstats, "memory.bandwidth.monitor.%zu.node.count", i);
+ virTypedParamListAddString(params, resdata[i]->name,
+ VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_PREFIX "%zu"
+ VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NAME, i);
+ virTypedParamListAddString(params, resdata[i]->vcpus,
+ VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_PREFIX "%zu"
+ VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_VCPUS, i);
+ virTypedParamListAddUInt(params, resdata[i]->nstats,
+ VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_PREFIX "%zu"
+ VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_COUNT, i);
for (j = 0; j < resdata[i]->nstats; j++) {
- virTypedParamListAddUInt(params, resdata[i]->stats[j]->id,
- "memory.bandwidth.monitor.%zu.node.%zu.id", i, j);
-
+ virTypedParamListAddUInt(
+ params, resdata[i]->stats[j]->id,
+ VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_PREFIX "%zu"
+ VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_PREFIX "%zu"
+ VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_SUFFIX_ID, i, j);
features = resdata[i]->stats[j]->features;
for (k = 0; features[k]; k++) {
if (STREQ(features[k], "mbm_local_bytes")) {
/* The accumulative data passing through local memory
* controller is recorded with 64 bit counter. */
- virTypedParamListAddULLong(params, resdata[i]->stats[j]->vals[k],
- "memory.bandwidth.monitor.%zu.node.%zu.bytes.local", i, j);
+ virTypedParamListAddULLong(
+ params, resdata[i]->stats[j]->vals[k],
+ VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_PREFIX "%zu"
+ VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_PREFIX "%zu"
+ VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_SUFFIX_BYTES_LOCAL, i, j);
}
if (STREQ(features[k], "mbm_total_bytes")) {
/* The accumulative data passing through local and remote
* memory controller is recorded with 64 bit counter. */
- virTypedParamListAddULLong(params, resdata[i]->stats[j]->vals[k],
- "memory.bandwidth.monitor.%zu.node.%zu.bytes.total", i, j);
+ virTypedParamListAddULLong(
+ params, resdata[i]->stats[j]->vals[k],
+ VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_PREFIX "%zu"
+ VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_PREFIX "%zu"
+ VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_SUFFIX_BYTES_TOTAL, i, j);
}
}
}
--
2.48.1
On Tue, Mar 04, 2025 at 14:04:11 +0000, Daniel P. Berrangé wrote: > Contrary to most APIs returning typed parameters, there are no constants > defined for the domain stats data keys. This is was because many of the > keys needs to be dynamically constructed using one or more array index > values. > > It is possible to define constants while still supporting dynamic > array indexes by simply defining the prefixes and suffixes as constants. > The consuming code can then combine the constants with array index > value. > > With this approach, it is practical to add constants for the domain stats > API keys. > > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> > --- > include/libvirt/libvirt-domain.h | 92 ++++++++++++++++++++++++++++++++ > src/libvirt-domain.c | 19 +------ > src/qemu/qemu_driver.c | 37 +++++++++---- > 3 files changed, 120 insertions(+), 28 deletions(-) [...] > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > index 76e121144d..d48e79d5c6 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -16722,32 +16722,47 @@ qemuDomainGetStatsMemoryBandwidth(virQEMUDriver *driver, [...] > for (j = 0; j < resdata[i]->nstats; j++) { > - virTypedParamListAddUInt(params, resdata[i]->stats[j]->id, > - "memory.bandwidth.monitor.%zu.node.%zu.id", i, j); > - > + virTypedParamListAddUInt( > + params, resdata[i]->stats[j]->id, > + VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_PREFIX "%zu" > + VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_PREFIX "%zu" > + VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_SUFFIX_ID, i, j); formatting > > features = resdata[i]->stats[j]->features; > for (k = 0; features[k]; k++) { > if (STREQ(features[k], "mbm_local_bytes")) { > /* The accumulative data passing through local memory > * controller is recorded with 64 bit counter. */ > - virTypedParamListAddULLong(params, resdata[i]->stats[j]->vals[k], > - "memory.bandwidth.monitor.%zu.node.%zu.bytes.local", i, j); > + virTypedParamListAddULLong( > + params, resdata[i]->stats[j]->vals[k], > + VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_PREFIX "%zu" > + VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_PREFIX "%zu" > + VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_SUFFIX_BYTES_LOCAL, i, j); ... > } > > if (STREQ(features[k], "mbm_total_bytes")) { > /* The accumulative data passing through local and remote > * memory controller is recorded with 64 bit counter. */ > - virTypedParamListAddULLong(params, resdata[i]->stats[j]->vals[k], > - "memory.bandwidth.monitor.%zu.node.%zu.bytes.total", i, j); > + virTypedParamListAddULLong( > + params, resdata[i]->stats[j]->vals[k], > + VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_PREFIX "%zu" > + VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_PREFIX "%zu" > + VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_SUFFIX_BYTES_TOTAL, i, j); ... Reviewed-by: Peter Krempa <pkrempa@redhat.com>
© 2016 - 2025 Red Hat, Inc.