mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 03:25:20 +00:00
qemu: monitor: Fix usage of 'query-blockstats'
Commit bc24810c2c
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 *
|
||||
qemuMonitorJSONQueryBlockstats(qemuMonitor *mon,
|
||||
bool queryNodes)
|
||||
@ -2475,13 +2499,14 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitor *mon,
|
||||
int nstats = 0;
|
||||
int rc;
|
||||
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;
|
||||
|
||||
for (i = 0; i < virJSONValueArraySize(devices); i++) {
|
||||
virJSONValue *dev = virJSONValueArrayGet(devices, i);
|
||||
for (i = 0; i < virJSONValueArraySize(blockstatsDevices); i++) {
|
||||
virJSONValue *dev = virJSONValueArrayGet(blockstatsDevices, i);
|
||||
const char *dev_name;
|
||||
|
||||
if (!dev || virJSONValueGetType(dev) != VIR_JSON_TYPE_OBJECT) {
|
||||
@ -2505,6 +2530,25 @@ qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitor *mon,
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1615,6 +1615,8 @@ testQemuMonitorJSONqemuMonitorJSONGetAllBlockStatsInfo(const void *opaque)
|
||||
|
||||
if (qemuMonitorTestAddItem(test, "query-blockstats", reply) < 0)
|
||||
return -1;
|
||||
if (qemuMonitorTestAddItem(test, "query-blockstats", reply) < 0)
|
||||
return -1;
|
||||
|
||||
#define CHECK0FULL(var, value, varformat, valformat) \
|
||||
if (stats->var != value) { \
|
||||
|
Loading…
Reference in New Issue
Block a user