mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-20 11:35:19 +00:00
qemu: monitor: Fix usage of 'query-blockstats'
Commit bc24810c2cab modified code querying blockstats to use the 'query-nodes' parameter so that we can fetch stats also for images which are not attached to a frontend such as block copy and backup scratch images. Unfortunately that broke the old blockstats because if 'query-nodes' is enabled qemu doesn't output the 'qdev' parameter which our code used for matching to the disk and also qemu neglects to populate the frontend stats at all so we can't even switch to using nodename for matching. To fix this we need to do two calls, one with 'query-nodes' disabled using the old logic to populate everything and then an additional one which populates all the remaining images. Closes: https://gitlab.com/libvirt/libvirt/-/issues/246 Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> Tested-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
parent
4b453bbb2f
commit
d120fc5253
@ -2446,6 +2446,30 @@ qemuMonitorJSONGetOneBlockStatsInfo(virJSONValue *dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemuMonitorJSONGetOneBlockStatsNodeInfo(virJSONValue *dev,
|
||||||
|
GHashTable *hash)
|
||||||
|
{
|
||||||
|
qemuBlockStats *bstats = NULL;
|
||||||
|
int nstats = 0;
|
||||||
|
const char *nodename = NULL;
|
||||||
|
|
||||||
|
if (!(nodename = virJSONValueObjectGetString(dev, "node-name")))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* we already have the stats */
|
||||||
|
if (g_hash_table_contains(hash, nodename))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!(bstats = qemuMonitorJSONBlockStatsCollectData(dev, &nstats)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
g_hash_table_insert(hash, g_strdup(nodename), bstats);
|
||||||
|
|
||||||
|
return nstats;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
virJSONValue *
|
virJSONValue *
|
||||||
qemuMonitorJSONQueryBlockstats(qemuMonitor *mon,
|
qemuMonitorJSONQueryBlockstats(qemuMonitor *mon,
|
||||||
bool queryNodes)
|
bool queryNodes)
|
||||||
@ -2475,13 +2499,14 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitor *mon,
|
|||||||
int nstats = 0;
|
int nstats = 0;
|
||||||
int rc;
|
int rc;
|
||||||
size_t i;
|
size_t i;
|
||||||
g_autoptr(virJSONValue) devices = NULL;
|
g_autoptr(virJSONValue) blockstatsDevices = NULL;
|
||||||
|
g_autoptr(virJSONValue) blockstatsNodes = NULL;
|
||||||
|
|
||||||
if (!(devices = qemuMonitorJSONQueryBlockstats(mon, true)))
|
if (!(blockstatsDevices = qemuMonitorJSONQueryBlockstats(mon, false)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
for (i = 0; i < virJSONValueArraySize(devices); i++) {
|
for (i = 0; i < virJSONValueArraySize(blockstatsDevices); i++) {
|
||||||
virJSONValue *dev = virJSONValueArrayGet(devices, i);
|
virJSONValue *dev = virJSONValueArrayGet(blockstatsDevices, i);
|
||||||
const char *dev_name;
|
const char *dev_name;
|
||||||
|
|
||||||
if (!dev || virJSONValueGetType(dev) != VIR_JSON_TYPE_OBJECT) {
|
if (!dev || virJSONValueGetType(dev) != VIR_JSON_TYPE_OBJECT) {
|
||||||
@ -2505,6 +2530,25 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitor *mon,
|
|||||||
nstats = rc;
|
nstats = rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(blockstatsNodes = qemuMonitorJSONQueryBlockstats(mon, true)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; i < virJSONValueArraySize(blockstatsNodes); i++) {
|
||||||
|
virJSONValue *dev = virJSONValueArrayGet(blockstatsNodes, i);
|
||||||
|
|
||||||
|
if (!dev || virJSONValueGetType(dev) != VIR_JSON_TYPE_OBJECT) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("blockstats device entry was not in expected format"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((rc = qemuMonitorJSONGetOneBlockStatsNodeInfo(dev, hash)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (rc > nstats)
|
||||||
|
nstats = rc;
|
||||||
|
}
|
||||||
|
|
||||||
return nstats;
|
return nstats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1615,6 +1615,8 @@ testQemuMonitorJSONqemuMonitorJSONGetAllBlockStatsInfo(const void *opaque)
|
|||||||
|
|
||||||
if (qemuMonitorTestAddItem(test, "query-blockstats", reply) < 0)
|
if (qemuMonitorTestAddItem(test, "query-blockstats", reply) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
if (qemuMonitorTestAddItem(test, "query-blockstats", reply) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
#define CHECK0FULL(var, value, varformat, valformat) \
|
#define CHECK0FULL(var, value, varformat, valformat) \
|
||||||
if (stats->var != value) { \
|
if (stats->var != value) { \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user